mirror of
https://github.com/robertkrimen/otto
synced 2025-10-05 19:19:10 +08:00
feat: add github action tests and linting (#418)
Leverage github actions for tests and linting. This includes fixing a bunch of issues highlighted by golangci including: * Dead code. * Ineffectual assigns. * Goto warnings. * Nil return err. * Reused literal strings. * Test parameter order. Also: * Setup clog.
This commit is contained in:
parent
209b1fb8e8
commit
9297a9abe4
13
.clog.toml
Normal file
13
.clog.toml
Normal file
|
@ -0,0 +1,13 @@
|
|||
[clog]
|
||||
repository = "https://github.com/robertkrimen/otto"
|
||||
subtitle = "Release Notes"
|
||||
|
||||
[sections]
|
||||
"Refactors" = ["refactor"]
|
||||
"Chores" = ["chore"]
|
||||
"Continuous Integration" = ["ci"]
|
||||
"Improvements" = ["imp", "improvement"]
|
||||
"Features" = ["feat", "feature"]
|
||||
"Legacy" = ["legacy"]
|
||||
"QA" = ["qa", "test", "tests"]
|
||||
"Documentation" = ["doc", "docs"]
|
24
.github/workflows/test-lint.yml
vendored
Normal file
24
.github/workflows/test-lint.yml
vendored
Normal file
|
@ -0,0 +1,24 @@
|
|||
name: Go test and lint
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: '**'
|
||||
|
||||
jobs:
|
||||
go-test-lint:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: 1.17
|
||||
|
||||
- name: Test
|
||||
run: go test -v ./...
|
||||
|
||||
- name: golangci-lint
|
||||
uses: golangci/golangci-lint-action@v2
|
||||
with:
|
||||
version: latest
|
79
.golangci.yml
Normal file
79
.golangci.yml
Normal file
|
@ -0,0 +1,79 @@
|
|||
run:
|
||||
concurrency: 4
|
||||
deadline: 5m
|
||||
skip-dirs:
|
||||
- terst
|
||||
skip-files:
|
||||
- dbg/dbg.go
|
||||
|
||||
linters-settings:
|
||||
govet:
|
||||
check-shadowing: false
|
||||
gocyclo:
|
||||
min-complexity: 20
|
||||
maligned:
|
||||
suggest-new: true
|
||||
dupl:
|
||||
threshold: 100
|
||||
goconst:
|
||||
min-len: 2
|
||||
min-occurrences: 4
|
||||
cyclop:
|
||||
max-complexity: 15
|
||||
|
||||
linters:
|
||||
enable-all: true
|
||||
disable:
|
||||
- dupl
|
||||
- gas
|
||||
- errcheck
|
||||
- gofmt
|
||||
- gosimple
|
||||
- interfacer
|
||||
- megacheck
|
||||
- maligned
|
||||
- structcheck
|
||||
- staticcheck
|
||||
- unconvert
|
||||
- unparam
|
||||
- varcheck
|
||||
- lll
|
||||
- prealloc
|
||||
- gochecknoglobals
|
||||
- gochecknoinits
|
||||
- scopelint
|
||||
- funlen
|
||||
- godox
|
||||
- exhaustivestruct
|
||||
- goerr113
|
||||
- wsl
|
||||
- nlreturn
|
||||
- tagliatelle
|
||||
- gomnd
|
||||
- paralleltest
|
||||
- wrapcheck
|
||||
- testpackage
|
||||
- golint
|
||||
- gofumpt
|
||||
- forbidigo
|
||||
- gocognit
|
||||
- gocritic
|
||||
- godot
|
||||
- nakedret
|
||||
- nestif
|
||||
- revive
|
||||
- whitespace
|
||||
- errorlint
|
||||
- exhaustive
|
||||
- forcetypeassert
|
||||
- ifshort
|
||||
- stylecheck
|
||||
- gocyclo
|
||||
- misspell
|
||||
- cyclop
|
||||
|
||||
issues:
|
||||
exclude:
|
||||
- .*Id.* should be .*ID.*
|
||||
exclude-use-default: false
|
||||
max-same-issues: 0
|
|
@ -2,6 +2,7 @@ package ast
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/robertkrimen/otto/file"
|
||||
)
|
||||
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
package ast
|
||||
|
||||
import (
|
||||
"github.com/robertkrimen/otto/file"
|
||||
"testing"
|
||||
|
||||
"github.com/robertkrimen/otto/file"
|
||||
)
|
||||
|
||||
func TestCommentMap(t *testing.T) {
|
||||
|
|
19
builtin.go
19
builtin.go
|
@ -41,22 +41,6 @@ func builtinGlobal_isFinite(call FunctionCall) Value {
|
|||
return toValue_bool(!math.IsNaN(value) && !math.IsInf(value, 0))
|
||||
}
|
||||
|
||||
// radix 3 => 2 (ASCII 50) +47
|
||||
// radix 11 => A/a (ASCII 65/97) +54/+86
|
||||
var parseInt_alphabetTable = func() []string {
|
||||
table := []string{"", "", "01"}
|
||||
for radix := 3; radix <= 36; radix += 1 {
|
||||
alphabet := table[radix-1]
|
||||
if radix <= 10 {
|
||||
alphabet += string(rune(radix + 47))
|
||||
} else {
|
||||
alphabet += string(rune(radix+54)) + string(rune(radix+86))
|
||||
}
|
||||
table = append(table, alphabet)
|
||||
}
|
||||
return table
|
||||
}()
|
||||
|
||||
func digitValue(chr rune) int {
|
||||
switch {
|
||||
case '0' <= chr && chr <= '9':
|
||||
|
@ -129,7 +113,7 @@ func builtinGlobal_parseInt(call FunctionCall) Value {
|
|||
for _, chr := range input {
|
||||
digit := float64(digitValue(chr))
|
||||
if digit >= base {
|
||||
goto error
|
||||
return NaNValue()
|
||||
}
|
||||
value = value*base + digit
|
||||
}
|
||||
|
@ -138,7 +122,6 @@ func builtinGlobal_parseInt(call FunctionCall) Value {
|
|||
}
|
||||
return toValue_float64(value)
|
||||
}
|
||||
error:
|
||||
return NaNValue()
|
||||
}
|
||||
if negative {
|
||||
|
|
|
@ -38,7 +38,7 @@ func builtinArray_toString(call FunctionCall) Value {
|
|||
func builtinArray_toLocaleString(call FunctionCall) Value {
|
||||
separator := ","
|
||||
thisObject := call.thisObject()
|
||||
length := int64(toUint32(thisObject.get("length")))
|
||||
length := int64(toUint32(thisObject.get(propertyLength)))
|
||||
if length == 0 {
|
||||
return toValue_string("")
|
||||
}
|
||||
|
@ -70,7 +70,7 @@ func builtinArray_concat(call FunctionCall) Value {
|
|||
case valueObject:
|
||||
object := item._object()
|
||||
if isArray(object) {
|
||||
length := object.get("length").number().int64
|
||||
length := object.get(propertyLength).number().int64
|
||||
for index := int64(0); index < length; index += 1 {
|
||||
name := strconv.FormatInt(index, 10)
|
||||
if object.hasProperty(name) {
|
||||
|
@ -91,9 +91,9 @@ func builtinArray_concat(call FunctionCall) Value {
|
|||
|
||||
func builtinArray_shift(call FunctionCall) Value {
|
||||
thisObject := call.thisObject()
|
||||
length := int64(toUint32(thisObject.get("length")))
|
||||
length := int64(toUint32(thisObject.get(propertyLength)))
|
||||
if 0 == length {
|
||||
thisObject.put("length", toValue_int64(0), true)
|
||||
thisObject.put(propertyLength, toValue_int64(0), true)
|
||||
return Value{}
|
||||
}
|
||||
first := thisObject.get("0")
|
||||
|
@ -107,34 +107,34 @@ func builtinArray_shift(call FunctionCall) Value {
|
|||
}
|
||||
}
|
||||
thisObject.delete(arrayIndexToString(length-1), true)
|
||||
thisObject.put("length", toValue_int64(length-1), true)
|
||||
thisObject.put(propertyLength, toValue_int64(length-1), true)
|
||||
return first
|
||||
}
|
||||
|
||||
func builtinArray_push(call FunctionCall) Value {
|
||||
thisObject := call.thisObject()
|
||||
itemList := call.ArgumentList
|
||||
index := int64(toUint32(thisObject.get("length")))
|
||||
index := int64(toUint32(thisObject.get(propertyLength)))
|
||||
for len(itemList) > 0 {
|
||||
thisObject.put(arrayIndexToString(index), itemList[0], true)
|
||||
itemList = itemList[1:]
|
||||
index += 1
|
||||
}
|
||||
length := toValue_int64(index)
|
||||
thisObject.put("length", length, true)
|
||||
thisObject.put(propertyLength, length, true)
|
||||
return length
|
||||
}
|
||||
|
||||
func builtinArray_pop(call FunctionCall) Value {
|
||||
thisObject := call.thisObject()
|
||||
length := int64(toUint32(thisObject.get("length")))
|
||||
length := int64(toUint32(thisObject.get(propertyLength)))
|
||||
if 0 == length {
|
||||
thisObject.put("length", toValue_uint32(0), true)
|
||||
thisObject.put(propertyLength, toValue_uint32(0), true)
|
||||
return Value{}
|
||||
}
|
||||
last := thisObject.get(arrayIndexToString(length - 1))
|
||||
thisObject.delete(arrayIndexToString(length-1), true)
|
||||
thisObject.put("length", toValue_int64(length-1), true)
|
||||
thisObject.put(propertyLength, toValue_int64(length-1), true)
|
||||
return last
|
||||
}
|
||||
|
||||
|
@ -147,7 +147,7 @@ func builtinArray_join(call FunctionCall) Value {
|
|||
}
|
||||
}
|
||||
thisObject := call.thisObject()
|
||||
length := int64(toUint32(thisObject.get("length")))
|
||||
length := int64(toUint32(thisObject.get(propertyLength)))
|
||||
if length == 0 {
|
||||
return toValue_string("")
|
||||
}
|
||||
|
@ -167,7 +167,7 @@ func builtinArray_join(call FunctionCall) Value {
|
|||
|
||||
func builtinArray_splice(call FunctionCall) Value {
|
||||
thisObject := call.thisObject()
|
||||
length := int64(toUint32(thisObject.get("length")))
|
||||
length := int64(toUint32(thisObject.get(propertyLength)))
|
||||
|
||||
start := valueToRangeIndex(call.Argument(0), length, false)
|
||||
deleteCount := length - start
|
||||
|
@ -240,7 +240,7 @@ func builtinArray_splice(call FunctionCall) Value {
|
|||
for index := int64(0); index < itemCount; index++ {
|
||||
thisObject.put(arrayIndexToString(index+start), itemList[index], true)
|
||||
}
|
||||
thisObject.put("length", toValue_int64(int64(length)+itemCount-deleteCount), true)
|
||||
thisObject.put(propertyLength, toValue_int64(int64(length)+itemCount-deleteCount), true)
|
||||
|
||||
return toValue_object(call.runtime.newArrayOf(valueArray))
|
||||
}
|
||||
|
@ -248,7 +248,7 @@ func builtinArray_splice(call FunctionCall) Value {
|
|||
func builtinArray_slice(call FunctionCall) Value {
|
||||
thisObject := call.thisObject()
|
||||
|
||||
length := int64(toUint32(thisObject.get("length")))
|
||||
length := int64(toUint32(thisObject.get(propertyLength)))
|
||||
start, end := rangeStartEnd(call.ArgumentList, length, false)
|
||||
|
||||
if start >= end {
|
||||
|
@ -270,7 +270,7 @@ func builtinArray_slice(call FunctionCall) Value {
|
|||
|
||||
func builtinArray_unshift(call FunctionCall) Value {
|
||||
thisObject := call.thisObject()
|
||||
length := int64(toUint32(thisObject.get("length")))
|
||||
length := int64(toUint32(thisObject.get(propertyLength)))
|
||||
itemList := call.ArgumentList
|
||||
itemCount := int64(len(itemList))
|
||||
|
||||
|
@ -289,13 +289,13 @@ func builtinArray_unshift(call FunctionCall) Value {
|
|||
}
|
||||
|
||||
newLength := toValue_int64(length + itemCount)
|
||||
thisObject.put("length", newLength, true)
|
||||
thisObject.put(propertyLength, newLength, true)
|
||||
return newLength
|
||||
}
|
||||
|
||||
func builtinArray_reverse(call FunctionCall) Value {
|
||||
thisObject := call.thisObject()
|
||||
length := int64(toUint32(thisObject.get("length")))
|
||||
length := int64(toUint32(thisObject.get(propertyLength)))
|
||||
|
||||
lower := struct {
|
||||
name string
|
||||
|
@ -454,7 +454,7 @@ func arraySortQuickSort(thisObject *_object, left, right uint, compare *_object)
|
|||
|
||||
func builtinArray_sort(call FunctionCall) Value {
|
||||
thisObject := call.thisObject()
|
||||
length := uint(toUint32(thisObject.get("length")))
|
||||
length := uint(toUint32(thisObject.get(propertyLength)))
|
||||
compareValue := call.Argument(0)
|
||||
compare := compareValue._object()
|
||||
if compareValue.IsUndefined() {
|
||||
|
@ -473,7 +473,7 @@ func builtinArray_isArray(call FunctionCall) Value {
|
|||
|
||||
func builtinArray_indexOf(call FunctionCall) Value {
|
||||
thisObject, matchValue := call.thisObject(), call.Argument(0)
|
||||
if length := int64(toUint32(thisObject.get("length"))); length > 0 {
|
||||
if length := int64(toUint32(thisObject.get(propertyLength))); length > 0 {
|
||||
index := int64(0)
|
||||
if len(call.ArgumentList) > 1 {
|
||||
index = call.Argument(1).number().int64
|
||||
|
@ -501,7 +501,7 @@ func builtinArray_indexOf(call FunctionCall) Value {
|
|||
|
||||
func builtinArray_lastIndexOf(call FunctionCall) Value {
|
||||
thisObject, matchValue := call.thisObject(), call.Argument(0)
|
||||
length := int64(toUint32(thisObject.get("length")))
|
||||
length := int64(toUint32(thisObject.get(propertyLength)))
|
||||
index := length - 1
|
||||
if len(call.ArgumentList) > 1 {
|
||||
index = call.Argument(1).number().int64
|
||||
|
@ -531,7 +531,7 @@ func builtinArray_every(call FunctionCall) Value {
|
|||
thisObject := call.thisObject()
|
||||
this := toValue_object(thisObject)
|
||||
if iterator := call.Argument(0); iterator.isCallable() {
|
||||
length := int64(toUint32(thisObject.get("length")))
|
||||
length := int64(toUint32(thisObject.get(propertyLength)))
|
||||
callThis := call.Argument(1)
|
||||
for index := int64(0); index < length; index++ {
|
||||
if key := arrayIndexToString(index); thisObject.hasProperty(key) {
|
||||
|
@ -550,7 +550,7 @@ func builtinArray_some(call FunctionCall) Value {
|
|||
thisObject := call.thisObject()
|
||||
this := toValue_object(thisObject)
|
||||
if iterator := call.Argument(0); iterator.isCallable() {
|
||||
length := int64(toUint32(thisObject.get("length")))
|
||||
length := int64(toUint32(thisObject.get(propertyLength)))
|
||||
callThis := call.Argument(1)
|
||||
for index := int64(0); index < length; index++ {
|
||||
if key := arrayIndexToString(index); thisObject.hasProperty(key) {
|
||||
|
@ -568,7 +568,7 @@ func builtinArray_forEach(call FunctionCall) Value {
|
|||
thisObject := call.thisObject()
|
||||
this := toValue_object(thisObject)
|
||||
if iterator := call.Argument(0); iterator.isCallable() {
|
||||
length := int64(toUint32(thisObject.get("length")))
|
||||
length := int64(toUint32(thisObject.get(propertyLength)))
|
||||
callThis := call.Argument(1)
|
||||
for index := int64(0); index < length; index++ {
|
||||
if key := arrayIndexToString(index); thisObject.hasProperty(key) {
|
||||
|
@ -584,7 +584,7 @@ func builtinArray_map(call FunctionCall) Value {
|
|||
thisObject := call.thisObject()
|
||||
this := toValue_object(thisObject)
|
||||
if iterator := call.Argument(0); iterator.isCallable() {
|
||||
length := int64(toUint32(thisObject.get("length")))
|
||||
length := int64(toUint32(thisObject.get(propertyLength)))
|
||||
callThis := call.Argument(1)
|
||||
values := make([]Value, length)
|
||||
for index := int64(0); index < length; index++ {
|
||||
|
@ -603,7 +603,7 @@ func builtinArray_filter(call FunctionCall) Value {
|
|||
thisObject := call.thisObject()
|
||||
this := toValue_object(thisObject)
|
||||
if iterator := call.Argument(0); iterator.isCallable() {
|
||||
length := int64(toUint32(thisObject.get("length")))
|
||||
length := int64(toUint32(thisObject.get(propertyLength)))
|
||||
callThis := call.Argument(1)
|
||||
values := make([]Value, 0)
|
||||
for index := int64(0); index < length; index++ {
|
||||
|
@ -625,7 +625,7 @@ func builtinArray_reduce(call FunctionCall) Value {
|
|||
if iterator := call.Argument(0); iterator.isCallable() {
|
||||
initial := len(call.ArgumentList) > 1
|
||||
start := call.Argument(1)
|
||||
length := int64(toUint32(thisObject.get("length")))
|
||||
length := int64(toUint32(thisObject.get(propertyLength)))
|
||||
index := int64(0)
|
||||
if length > 0 || initial {
|
||||
var accumulator Value
|
||||
|
@ -657,7 +657,7 @@ func builtinArray_reduceRight(call FunctionCall) Value {
|
|||
if iterator := call.Argument(0); iterator.isCallable() {
|
||||
initial := len(call.ArgumentList) > 1
|
||||
start := call.Argument(1)
|
||||
length := int64(toUint32(thisObject.get("length")))
|
||||
length := int64(toUint32(thisObject.get(propertyLength)))
|
||||
if length > 0 || initial {
|
||||
index := length - 1
|
||||
var accumulator Value
|
||||
|
|
|
@ -14,7 +14,7 @@ func builtinBoolean_toString(call FunctionCall) Value {
|
|||
value := call.This
|
||||
if !value.IsBoolean() {
|
||||
// Will throw a TypeError if ThisObject is not a Boolean
|
||||
value = call.thisClassObject("Boolean").primitiveValue()
|
||||
value = call.thisClassObject(classBoolean).primitiveValue()
|
||||
}
|
||||
return toValue_string(value.string())
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ func builtinBoolean_toString(call FunctionCall) Value {
|
|||
func builtinBoolean_valueOf(call FunctionCall) Value {
|
||||
value := call.This
|
||||
if !value.IsBoolean() {
|
||||
value = call.thisClassObject("Boolean").primitiveValue()
|
||||
value = call.thisClassObject(classBoolean).primitiveValue()
|
||||
}
|
||||
return value
|
||||
}
|
||||
|
|
|
@ -5,11 +5,11 @@ import (
|
|||
)
|
||||
|
||||
func builtinError(call FunctionCall) Value {
|
||||
return toValue_object(call.runtime.newError("Error", call.Argument(0), 1))
|
||||
return toValue_object(call.runtime.newError(classError, call.Argument(0), 1))
|
||||
}
|
||||
|
||||
func builtinNewError(self *_object, argumentList []Value) Value {
|
||||
return toValue_object(self.runtime.newError("Error", valueOfArrayIndex(argumentList, 0), 0))
|
||||
return toValue_object(self.runtime.newError(classError, valueOfArrayIndex(argumentList, 0), 0))
|
||||
}
|
||||
|
||||
func builtinError_toString(call FunctionCall) Value {
|
||||
|
@ -18,7 +18,7 @@ func builtinError_toString(call FunctionCall) Value {
|
|||
panic(call.runtime.panicTypeError())
|
||||
}
|
||||
|
||||
name := "Error"
|
||||
name := classError
|
||||
nameValue := thisObject.get("name")
|
||||
if nameValue.IsDefined() {
|
||||
name = nameValue.string()
|
||||
|
|
|
@ -2,7 +2,6 @@ package otto
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
"unicode"
|
||||
|
||||
|
@ -30,8 +29,6 @@ func argumentList2parameterList(argumentList []Value) []string {
|
|||
return parameterList
|
||||
}
|
||||
|
||||
var matchIdentifier = regexp.MustCompile(`^[$_\p{L}][$_\p{L}\d}]*$`)
|
||||
|
||||
func builtinNewFunctionNative(runtime *_runtime, argumentList []Value) *_object {
|
||||
var parameterList, body string
|
||||
count := len(argumentList)
|
||||
|
@ -54,7 +51,7 @@ func builtinNewFunctionNative(runtime *_runtime, argumentList []Value) *_object
|
|||
}
|
||||
|
||||
func builtinFunction_toString(call FunctionCall) Value {
|
||||
object := call.thisClassObject("Function") // Should throw a TypeError unless Function
|
||||
object := call.thisClassObject(classFunction) // Should throw a TypeError unless Function
|
||||
switch fn := object.value.(type) {
|
||||
case _nativeFunctionObject:
|
||||
return toValue_string(fmt.Sprintf("function %s() { [native code] }", fn.name))
|
||||
|
@ -87,7 +84,7 @@ func builtinFunction_apply(call FunctionCall) Value {
|
|||
|
||||
arrayObject := argumentList._object()
|
||||
thisObject := call.thisObject()
|
||||
length := int64(toUint32(arrayObject.get("length")))
|
||||
length := int64(toUint32(arrayObject.get(propertyLength)))
|
||||
valueArray := make([]Value, length)
|
||||
for index := int64(0); index < length; index++ {
|
||||
valueArray[index] = arrayObject.get(arrayIndexToString(index))
|
||||
|
|
|
@ -123,8 +123,8 @@ func builtinJSON_stringify(call FunctionCall) Value {
|
|||
switch value.kind {
|
||||
case valueObject:
|
||||
switch value.value.(*_object).class {
|
||||
case "String":
|
||||
case "Number":
|
||||
case classString:
|
||||
case classNumber:
|
||||
default:
|
||||
continue
|
||||
}
|
||||
|
@ -142,7 +142,7 @@ func builtinJSON_stringify(call FunctionCall) Value {
|
|||
propertyList[index] = name
|
||||
}
|
||||
ctx.propertyList = propertyList[0:length]
|
||||
} else if replacer.class == "Function" {
|
||||
} else if replacer.class == classFunction {
|
||||
value := toValue_object(replacer)
|
||||
ctx.replacerFunction = &value
|
||||
}
|
||||
|
@ -150,9 +150,9 @@ func builtinJSON_stringify(call FunctionCall) Value {
|
|||
if spaceValue, exists := call.getArgument(2); exists {
|
||||
if spaceValue.kind == valueObject {
|
||||
switch spaceValue.value.(*_object).class {
|
||||
case "String":
|
||||
case classString:
|
||||
spaceValue = toValue_string(spaceValue.string())
|
||||
case "Number":
|
||||
case classNumber:
|
||||
spaceValue = spaceValue.numberValue()
|
||||
}
|
||||
}
|
||||
|
@ -216,11 +216,11 @@ func builtinJSON_stringifyWalk(ctx _builtinJSON_stringifyContext, key string, ho
|
|||
|
||||
if value.kind == valueObject {
|
||||
switch value.value.(*_object).class {
|
||||
case "Boolean":
|
||||
case classBoolean:
|
||||
value = value._object().value.(Value)
|
||||
case "String":
|
||||
case classString:
|
||||
value = toValue_string(value.string())
|
||||
case "Number":
|
||||
case classNumber:
|
||||
value = value.numberValue()
|
||||
}
|
||||
}
|
||||
|
@ -255,7 +255,7 @@ func builtinJSON_stringifyWalk(ctx _builtinJSON_stringifyContext, key string, ho
|
|||
}
|
||||
if isArray(holder) {
|
||||
var length uint32
|
||||
switch value := holder.get("length").value.(type) {
|
||||
switch value := holder.get(propertyLength).value.(type) {
|
||||
case uint32:
|
||||
length = value
|
||||
case int:
|
||||
|
@ -272,7 +272,7 @@ func builtinJSON_stringifyWalk(ctx _builtinJSON_stringifyContext, key string, ho
|
|||
array[index] = value
|
||||
}
|
||||
return array, true
|
||||
} else if holder.class != "Function" {
|
||||
} else if holder.class != classFunction {
|
||||
object := map[string]interface{}{}
|
||||
if ctx.propertyList != nil {
|
||||
for _, name := range ctx.propertyList {
|
||||
|
|
|
@ -24,7 +24,7 @@ func builtinNewNumber(self *_object, argumentList []Value) Value {
|
|||
|
||||
func builtinNumber_toString(call FunctionCall) Value {
|
||||
// Will throw a TypeError if ThisObject is not a Number
|
||||
value := call.thisClassObject("Number").primitiveValue()
|
||||
value := call.thisClassObject(classNumber).primitiveValue()
|
||||
radix := 10
|
||||
radixArgument := call.Argument(0)
|
||||
if radixArgument.IsDefined() {
|
||||
|
@ -41,7 +41,7 @@ func builtinNumber_toString(call FunctionCall) Value {
|
|||
}
|
||||
|
||||
func builtinNumber_valueOf(call FunctionCall) Value {
|
||||
return call.thisClassObject("Number").primitiveValue()
|
||||
return call.thisClassObject(classNumber).primitiveValue()
|
||||
}
|
||||
|
||||
func builtinNumber_toFixed(call FunctionCall) Value {
|
||||
|
|
|
@ -66,7 +66,7 @@ func builtinObject_propertyIsEnumerable(call FunctionCall) Value {
|
|||
}
|
||||
|
||||
func builtinObject_toString(call FunctionCall) Value {
|
||||
result := ""
|
||||
var result string
|
||||
if call.This.IsUndefined() {
|
||||
result = "[object Undefined]"
|
||||
} else if call.This.IsNull() {
|
||||
|
|
|
@ -10,7 +10,7 @@ func builtinRegExp(call FunctionCall) Value {
|
|||
pattern := call.Argument(0)
|
||||
flags := call.Argument(1)
|
||||
if object := pattern._object(); object != nil {
|
||||
if object.class == "RegExp" && flags.IsUndefined() {
|
||||
if object.class == classRegExp && flags.IsUndefined() {
|
||||
return pattern
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,10 +26,10 @@ func builtinNewString(self *_object, argumentList []Value) Value {
|
|||
}
|
||||
|
||||
func builtinString_toString(call FunctionCall) Value {
|
||||
return call.thisClassObject("String").primitiveValue()
|
||||
return call.thisClassObject(classString).primitiveValue()
|
||||
}
|
||||
func builtinString_valueOf(call FunctionCall) Value {
|
||||
return call.thisClassObject("String").primitiveValue()
|
||||
return call.thisClassObject(classString).primitiveValue()
|
||||
}
|
||||
|
||||
func builtinString_fromCharCode(call FunctionCall) Value {
|
||||
|
@ -124,7 +124,7 @@ func builtinString_match(call FunctionCall) Value {
|
|||
target := call.This.string()
|
||||
matcherValue := call.Argument(0)
|
||||
matcher := matcherValue._object()
|
||||
if !matcherValue.IsObject() || matcher.class != "RegExp" {
|
||||
if !matcherValue.IsObject() || matcher.class != classRegExp {
|
||||
matcher = call.runtime.newRegExp(matcherValue, Value{})
|
||||
}
|
||||
global := matcher.get("global").bool()
|
||||
|
@ -138,12 +138,11 @@ func builtinString_match(call FunctionCall) Value {
|
|||
|
||||
{
|
||||
result := matcher.regExpValue().regularExpression.FindAllStringIndex(target, -1)
|
||||
matchCount := len(result)
|
||||
if result == nil {
|
||||
matcher.put("lastIndex", toValue_int(0), true)
|
||||
return Value{} // !match
|
||||
}
|
||||
matchCount = len(result)
|
||||
matchCount := len(result)
|
||||
valueArray := make([]Value, matchCount)
|
||||
for index := 0; index < matchCount; index++ {
|
||||
valueArray[index] = toValue_string(target[result[index][0]:result[index][1]])
|
||||
|
@ -173,9 +172,12 @@ func builtinString_findAndReplaceString(input []byte, lastIndex int, match []int
|
|||
case '\'':
|
||||
return target[match[1]:len(target)]
|
||||
}
|
||||
matchNumberParse, error := strconv.ParseInt(string(part[1:]), 10, 64)
|
||||
matchNumberParse, err := strconv.ParseInt(string(part[1:]), 10, 64)
|
||||
if err != nil {
|
||||
return []byte{}
|
||||
}
|
||||
matchNumber := int(matchNumberParse)
|
||||
if error != nil || matchNumber >= matchCount {
|
||||
if matchNumber >= matchCount {
|
||||
return []byte{}
|
||||
}
|
||||
offset := 2 * matchNumber
|
||||
|
@ -198,7 +200,7 @@ func builtinString_replace(call FunctionCall) Value {
|
|||
var search *regexp.Regexp
|
||||
global := false
|
||||
find := 1
|
||||
if searchValue.IsObject() && searchObject.class == "RegExp" {
|
||||
if searchValue.IsObject() && searchObject.class == classRegExp {
|
||||
regExp := searchObject.regExpValue()
|
||||
search = regExp.regularExpression
|
||||
if regExp.global {
|
||||
|
@ -267,7 +269,7 @@ func builtinString_search(call FunctionCall) Value {
|
|||
target := call.This.string()
|
||||
searchValue := call.Argument(0)
|
||||
search := searchValue._object()
|
||||
if !searchValue.IsObject() || search.class != "RegExp" {
|
||||
if !searchValue.IsObject() || search.class != classRegExp {
|
||||
search = call.runtime.newRegExp(searchValue, Value{})
|
||||
}
|
||||
result := search.regExpValue().regularExpression.FindStringIndex(target)
|
||||
|
@ -277,17 +279,6 @@ func builtinString_search(call FunctionCall) Value {
|
|||
return toValue_int(result[0])
|
||||
}
|
||||
|
||||
func stringSplitMatch(target string, targetLength int64, index uint, search string, searchLength int64) (bool, uint) {
|
||||
if int64(index)+searchLength > searchLength {
|
||||
return false, 0
|
||||
}
|
||||
found := strings.Index(target[index:], search)
|
||||
if 0 > found {
|
||||
return false, 0
|
||||
}
|
||||
return true, uint(found)
|
||||
}
|
||||
|
||||
func builtinString_split(call FunctionCall) Value {
|
||||
checkObjectCoercible(call.runtime, call.This)
|
||||
target := call.This.string()
|
||||
|
|
12
call_test.go
12
call_test.go
|
@ -5,6 +5,10 @@ import (
|
|||
"testing"
|
||||
)
|
||||
|
||||
const (
|
||||
testAb = "ab"
|
||||
)
|
||||
|
||||
func BenchmarkNativeCallWithString(b *testing.B) {
|
||||
vm := New()
|
||||
vm.Set("x", func(a1 string) {})
|
||||
|
@ -1405,7 +1409,7 @@ func TestNativeCallMethodWithStruct(t *testing.T) {
|
|||
vm.Set("x", testNativeCallWithStruct{Prefix: "a"})
|
||||
|
||||
vm.Set("t", func(s string) {
|
||||
if s != "ab" {
|
||||
if s != testAb {
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
|
@ -1432,7 +1436,7 @@ func TestNativeCallPointerMethodWithStruct(t *testing.T) {
|
|||
vm.Set("x", &testNativeCallWithStruct{Prefix: "a"})
|
||||
|
||||
vm.Set("t", func(s string) {
|
||||
if s != "ab" {
|
||||
if s != testAb {
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
|
@ -1459,7 +1463,7 @@ func TestNativeCallMethodWithStructPointer(t *testing.T) {
|
|||
vm.Set("x", testNativeCallWithStruct{Prefix: "a"})
|
||||
|
||||
vm.Set("t", func(s string) {
|
||||
if s != "ab" {
|
||||
if s != testAb {
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
|
@ -1486,7 +1490,7 @@ func TestNativeCallPointerMethodWithStructPointer(t *testing.T) {
|
|||
vm.Set("x", &testNativeCallWithStruct{Prefix: "a"})
|
||||
|
||||
vm.Set("t", func(s string) {
|
||||
if s != "ab" {
|
||||
if s != testAb {
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
|
|
6
cmpl.go
6
cmpl.go
|
@ -5,12 +5,6 @@ import (
|
|||
"github.com/robertkrimen/otto/file"
|
||||
)
|
||||
|
||||
type _file struct {
|
||||
name string
|
||||
src string
|
||||
base int // This will always be 1 or greater
|
||||
}
|
||||
|
||||
type _compiler struct {
|
||||
file *file.File
|
||||
program *ast.Program
|
||||
|
|
18
consts.go
Normal file
18
consts.go
Normal file
|
@ -0,0 +1,18 @@
|
|||
package otto
|
||||
|
||||
const (
|
||||
// Common classes.
|
||||
classString = "String"
|
||||
classGoArray = "GoArray"
|
||||
classNumber = "Number"
|
||||
classDate = "Date"
|
||||
classArray = "Array"
|
||||
classFunction = "Function"
|
||||
classObject = "Object"
|
||||
classRegExp = "RegExp"
|
||||
classBoolean = "Boolean"
|
||||
classError = "Error"
|
||||
|
||||
// Common properties.
|
||||
propertyLength = "length"
|
||||
)
|
|
@ -4,8 +4,7 @@ import (
|
|||
"fmt"
|
||||
)
|
||||
|
||||
func ExampleSynopsis() {
|
||||
|
||||
func ExampleSynopsis() { // nolint: govet
|
||||
vm := New()
|
||||
vm.Run(`
|
||||
abc = 2 + 2;
|
||||
|
@ -70,8 +69,7 @@ func ExampleSynopsis() {
|
|||
// 4
|
||||
}
|
||||
|
||||
func ExampleConsole() {
|
||||
|
||||
func ExampleConsole() { // nolint: govet
|
||||
vm := New()
|
||||
console := map[string]interface{}{
|
||||
"log": func(call FunctionCall) Value {
|
||||
|
@ -81,10 +79,11 @@ func ExampleConsole() {
|
|||
}
|
||||
|
||||
err := vm.Set("console", console)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("console error: %w", err))
|
||||
}
|
||||
|
||||
value, err := vm.Run(`
|
||||
console.log("Hello, World.");
|
||||
`)
|
||||
value, err := vm.Run(`console.log("Hello, World.");`)
|
||||
fmt.Println(value)
|
||||
fmt.Println(err)
|
||||
|
||||
|
|
|
@ -272,7 +272,7 @@ func TestMakeCustomErrorReturn(t *testing.T) {
|
|||
panic(err)
|
||||
}
|
||||
|
||||
is(v.Class(), "Error")
|
||||
is(v.Class(), classError)
|
||||
|
||||
name, err := v.Object().Get("name")
|
||||
if err != nil {
|
||||
|
@ -306,8 +306,6 @@ func TestMakeCustomError(t *testing.T) {
|
|||
|
||||
vm.Set("A", func(c FunctionCall) Value {
|
||||
panic(vm.MakeCustomError("CarrotError", "carrots is life, carrots is love"))
|
||||
|
||||
return UndefinedValue()
|
||||
})
|
||||
|
||||
s, _ := vm.Compile("test.js", `
|
||||
|
@ -354,8 +352,6 @@ func TestMakeTypeError(t *testing.T) {
|
|||
|
||||
vm.Set("A", func(c FunctionCall) Value {
|
||||
panic(vm.MakeTypeError("these aren't my glasses"))
|
||||
|
||||
return UndefinedValue()
|
||||
})
|
||||
|
||||
s, _ := vm.Compile("test.js", `
|
||||
|
@ -388,8 +384,6 @@ func TestMakeRangeError(t *testing.T) {
|
|||
|
||||
vm.Set("A", func(c FunctionCall) Value {
|
||||
panic(vm.MakeRangeError("too many"))
|
||||
|
||||
return UndefinedValue()
|
||||
})
|
||||
|
||||
s, _ := vm.Compile("test.js", `
|
||||
|
@ -422,8 +416,6 @@ func TestMakeSyntaxError(t *testing.T) {
|
|||
|
||||
vm.Set("A", func(c FunctionCall) Value {
|
||||
panic(vm.MakeSyntaxError("i think you meant \"you're\""))
|
||||
|
||||
return UndefinedValue()
|
||||
})
|
||||
|
||||
s, _ := vm.Compile("test.js", `
|
||||
|
|
24
evaluate.go
24
evaluate.go
|
@ -140,23 +140,6 @@ func (self *_runtime) calculateBinaryExpression(operator token.Token, left Value
|
|||
panic(hereBeDragons(operator))
|
||||
}
|
||||
|
||||
func valueKindDispatchKey(left _valueKind, right _valueKind) int {
|
||||
return (int(left) << 2) + int(right)
|
||||
}
|
||||
|
||||
var equalDispatch map[int](func(Value, Value) bool) = makeEqualDispatch()
|
||||
|
||||
func makeEqualDispatch() map[int](func(Value, Value) bool) {
|
||||
key := valueKindDispatchKey
|
||||
return map[int](func(Value, Value) bool){
|
||||
|
||||
key(valueNumber, valueObject): func(x Value, y Value) bool { return x.float64() == y.float64() },
|
||||
key(valueString, valueObject): func(x Value, y Value) bool { return x.float64() == y.float64() },
|
||||
key(valueObject, valueNumber): func(x Value, y Value) bool { return x.float64() == y.float64() },
|
||||
key(valueObject, valueString): func(x Value, y Value) bool { return x.float64() == y.float64() },
|
||||
}
|
||||
}
|
||||
|
||||
type _lessThanResult int
|
||||
|
||||
const (
|
||||
|
@ -166,10 +149,7 @@ const (
|
|||
)
|
||||
|
||||
func calculateLessThan(left Value, right Value, leftFirst bool) _lessThanResult {
|
||||
|
||||
x := Value{}
|
||||
y := x
|
||||
|
||||
var x, y Value
|
||||
if leftFirst {
|
||||
x = toNumberPrimitive(left)
|
||||
y = toNumberPrimitive(right)
|
||||
|
@ -178,7 +158,7 @@ func calculateLessThan(left Value, right Value, leftFirst bool) _lessThanResult
|
|||
x = toNumberPrimitive(left)
|
||||
}
|
||||
|
||||
result := false
|
||||
var result bool
|
||||
if x.kind != valueString || y.kind != valueString {
|
||||
x, y := x.float64(), y.float64()
|
||||
if math.IsNaN(x) || math.IsNaN(y) {
|
||||
|
|
|
@ -8,23 +8,23 @@ import (
|
|||
)
|
||||
|
||||
func TestGoSliceQuickSort(t *testing.T) {
|
||||
testGoSliceSort("quickSort(testSlice, 0, testSlice.length-1);", jsQuickSort, t)
|
||||
testGoSliceSort(t, "quickSort(testSlice, 0, testSlice.length-1);", jsQuickSort)
|
||||
}
|
||||
|
||||
func TestGoSliceHeapSort(t *testing.T) {
|
||||
testGoSliceSort("heapSort(testSlice)", jsHeapSort, t)
|
||||
testGoSliceSort(t, "heapSort(testSlice)", jsHeapSort)
|
||||
}
|
||||
|
||||
func TestJsArrayQuicksort(t *testing.T) {
|
||||
testJsArraySort("quickSort(testSlice, 0, testSlice.length-1);", jsQuickSort, t)
|
||||
testJsArraySort(t, "quickSort(testSlice, 0, testSlice.length-1);", jsQuickSort)
|
||||
}
|
||||
|
||||
func TestJsArrayHeapSort(t *testing.T) {
|
||||
testJsArraySort("heapSort(testSlice)", jsHeapSort, t)
|
||||
testJsArraySort(t, "heapSort(testSlice)", jsHeapSort)
|
||||
}
|
||||
|
||||
func TestJsArrayMergeSort(t *testing.T) {
|
||||
testJsArraySort("testSlice = mergeSort(testSlice)", jsMergeSort, t)
|
||||
testJsArraySort(t, "testSlice = mergeSort(testSlice)", jsMergeSort)
|
||||
}
|
||||
|
||||
func TestCryptoAes(t *testing.T) {
|
||||
|
@ -36,27 +36,26 @@ func TestCryptoAes(t *testing.T) {
|
|||
}
|
||||
|
||||
func BenchmarkGoSliceQuickSort100000000(b *testing.B) {
|
||||
benchmarkGoSliceSort(100000000, "quickSort(testSlice, 0, testSlice.length-1);", jsQuickSort, b)
|
||||
benchmarkGoSliceSort(b, 100000000, "quickSort(testSlice, 0, testSlice.length-1);", jsQuickSort)
|
||||
}
|
||||
|
||||
func BenchmarkGoSliceHeapSort100000000(b *testing.B) {
|
||||
benchmarkGoSliceSort(100000000, "heapSort(testSlice);", jsHeapSort, b)
|
||||
benchmarkGoSliceSort(b, 100000000, "heapSort(testSlice);", jsHeapSort)
|
||||
}
|
||||
|
||||
func BenchmarkJsArrayQuickSort10000(b *testing.B) {
|
||||
benchmarkJsArraySort(10000, "quickSort(testSlice, 0, testSlice.length-1);", jsQuickSort, b)
|
||||
benchmarkJsArraySort(b, 10000, "quickSort(testSlice, 0, testSlice.length-1);", jsQuickSort)
|
||||
}
|
||||
|
||||
func BenchmarkJsArrayMergeSort10000(b *testing.B) {
|
||||
benchmarkJsArraySort(10000, "mergeSort(testSlice);", jsMergeSort, b)
|
||||
benchmarkJsArraySort(b, 10000, "mergeSort(testSlice);", jsMergeSort)
|
||||
}
|
||||
|
||||
func BenchmarkJsArrayHeapSort10000(b *testing.B) {
|
||||
benchmarkJsArraySort(10000, "heapSort(testSlice);", jsHeapSort, b)
|
||||
benchmarkJsArraySort(b, 10000, "heapSort(testSlice);", jsHeapSort)
|
||||
}
|
||||
|
||||
func BenchmarkCryptoAES(b *testing.B) {
|
||||
|
||||
vm := New()
|
||||
|
||||
// Make sure VM creation time is not counted in runtime test
|
||||
|
@ -67,7 +66,8 @@ func BenchmarkCryptoAES(b *testing.B) {
|
|||
}
|
||||
}
|
||||
|
||||
func testGoSliceSort(sortFuncCall string, sortCode string, t *testing.T) {
|
||||
func testGoSliceSort(t *testing.T, sortFuncCall string, sortCode string) {
|
||||
t.Helper()
|
||||
tt(t, func() {
|
||||
test, vm := test()
|
||||
|
||||
|
@ -94,7 +94,8 @@ func testGoSliceSort(sortFuncCall string, sortCode string, t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
func testJsArraySort(sortFuncCall string, sortCode string, t *testing.T) {
|
||||
func testJsArraySort(t *testing.T, sortFuncCall string, sortCode string) {
|
||||
t.Helper()
|
||||
tt(t, func() {
|
||||
test, vm := test()
|
||||
|
||||
|
@ -113,7 +114,8 @@ func testJsArraySort(sortFuncCall string, sortCode string, t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
func benchmarkGoSliceSort(size int, sortFuncCall string, sortCode string, b *testing.B) {
|
||||
func benchmarkGoSliceSort(b *testing.B, size int, sortFuncCall string, sortCode string) {
|
||||
b.Helper()
|
||||
// generate arbitrary slice of 'size'
|
||||
testSlice := make([]int, size)
|
||||
for i := 0; i < size; i++ {
|
||||
|
@ -133,7 +135,8 @@ func benchmarkGoSliceSort(size int, sortFuncCall string, sortCode string, b *tes
|
|||
}
|
||||
}
|
||||
|
||||
func benchmarkJsArraySort(size int, sortFuncCall string, sortCode string, b *testing.B) {
|
||||
func benchmarkJsArraySort(b *testing.B, size int, sortFuncCall string, sortCode string) {
|
||||
b.Helper()
|
||||
// generate arbitrary slice of 'size'
|
||||
testSlice := make([]string, size)
|
||||
for i, _ := range testSlice {
|
||||
|
|
|
@ -90,7 +90,7 @@ func (self *_object) hasPrimitive() bool {
|
|||
}
|
||||
|
||||
func (runtime *_runtime) newObject() *_object {
|
||||
self := runtime.newClassObject("Object")
|
||||
self := runtime.newClassObject(classObject)
|
||||
self.prototype = runtime.global.ObjectPrototype
|
||||
return self
|
||||
}
|
||||
|
@ -134,7 +134,7 @@ func (runtime *_runtime) newRegExp(patternValue Value, flagsValue Value) *_objec
|
|||
|
||||
pattern := ""
|
||||
flags := ""
|
||||
if object := patternValue._object(); object != nil && object.class == "RegExp" {
|
||||
if object := patternValue._object(); object != nil && object.class == classRegExp {
|
||||
if flagsValue.IsDefined() {
|
||||
panic(runtime.panicTypeError("Cannot supply flags when constructing one RegExp from another"))
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ func TestGlobal(t *testing.T) {
|
|||
|
||||
// FIXME enterGlobalScope
|
||||
if false {
|
||||
value := runtime.scope.lexical.getBinding("Object", false)._object().call(UndefinedValue(), []Value{toValue(runtime.newObject())}, false, nativeFrame)
|
||||
value := runtime.scope.lexical.getBinding(classObject, false)._object().call(UndefinedValue(), []Value{toValue(runtime.newObject())}, false, nativeFrame)
|
||||
is(value.IsObject(), true)
|
||||
is(value, "[object Object]")
|
||||
is(value._object().prototype == runtime.global.ObjectPrototype, true)
|
||||
|
@ -51,16 +51,16 @@ func TestGlobal(t *testing.T) {
|
|||
is(call(value, "propertyIsEnumerable", "xyzzy"), true)
|
||||
is(value._object().get("xyzzy"), "Nothing happens.")
|
||||
|
||||
is(call(runtime.scope.lexical.getBinding("Object", false), "isPrototypeOf", value), false)
|
||||
is(call(runtime.scope.lexical.getBinding("Object", false)._object().get("prototype"), "isPrototypeOf", value), true)
|
||||
is(call(runtime.scope.lexical.getBinding("Function", false), "isPrototypeOf", value), false)
|
||||
is(call(runtime.scope.lexical.getBinding(classObject, false), "isPrototypeOf", value), false)
|
||||
is(call(runtime.scope.lexical.getBinding(classObject, false)._object().get("prototype"), "isPrototypeOf", value), true)
|
||||
is(call(runtime.scope.lexical.getBinding(classFunction, false), "isPrototypeOf", value), false)
|
||||
|
||||
is(runtime.newObject().prototype == runtime.global.Object.get("prototype")._object(), true)
|
||||
|
||||
abc := runtime.newBoolean(toValue_bool(true))
|
||||
is(toValue_object(abc), "true") // TODO Call primitive?
|
||||
|
||||
//def := runtime.localGet("Boolean")._object().Construct(UndefinedValue(), []Value{})
|
||||
//def := runtime.localGet(classBoolean)._object().Construct(UndefinedValue(), []Value{})
|
||||
//is(def, "false") // TODO Call primitive?
|
||||
}
|
||||
}
|
||||
|
|
3
go.sum
3
go.sum
|
@ -1,5 +1,8 @@
|
|||
github.com/chzyer/logex v1.1.10 h1:Swpa1K6QvQznwJRcfTfQJmTE72DqScAa40E+fbHEXEE=
|
||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1 h1:q763qf9huN11kDQavWsoZXJNW3xEE4JJyHa5Q25/sd8=
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
gopkg.in/readline.v1 v1.0.0-20160726135117-62c6fe619375 h1:hPki/oSSWOLiI9Gc9jyIoj33O3j29fUc9PlLha2yDj0=
|
||||
gopkg.in/readline.v1 v1.0.0-20160726135117-62c6fe619375/go.mod h1:lNEQeAhU009zbRxng+XOj5ITVgY24WcbNnQopyfKoYQ=
|
||||
gopkg.in/sourcemap.v1 v1.0.5 h1:inv58fC9f9J3TK2Y2R1NPntXEn3/wjWHkonhIUODNTI=
|
||||
gopkg.in/sourcemap.v1 v1.0.5/go.mod h1:2RlvNNSMglmRrcvhfuzp4hQHwOtjxlbjX7UPY/GXb78=
|
||||
|
|
|
@ -72,7 +72,7 @@ const (
|
|||
// 8.12.8
|
||||
func (self *_object) DefaultValue(hint _defaultValueHint) Value {
|
||||
if hint == defaultValueNoHint {
|
||||
if self.class == "Date" {
|
||||
if self.class == classDate {
|
||||
// Date exception
|
||||
hint = defaultValueHintString
|
||||
} else {
|
||||
|
|
28
otto_.go
28
otto_.go
|
@ -5,7 +5,6 @@ import (
|
|||
"regexp"
|
||||
runtime_ "runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var isIdentifier_Regexp *regexp.Regexp = regexp.MustCompile(`^[a-zA-Z\$][a-zA-Z0-9\$]*$`)
|
||||
|
@ -134,16 +133,8 @@ func rangeStartLength(source []Value, size int64) (start, length int64) {
|
|||
return
|
||||
}
|
||||
|
||||
func boolFields(input string) (result map[string]bool) {
|
||||
result = map[string]bool{}
|
||||
for _, word := range strings.Fields(input) {
|
||||
result[word] = true
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func hereBeDragons(arguments ...interface{}) string {
|
||||
pc, _, _, _ := runtime_.Caller(1)
|
||||
pc, _, _, _ := runtime_.Caller(1) // nolint: dogsled
|
||||
name := runtime_.FuncForPC(pc).Name()
|
||||
message := fmt.Sprintf("Here be dragons -- %s", name)
|
||||
if len(arguments) > 0 {
|
||||
|
@ -159,20 +150,3 @@ func hereBeDragons(arguments ...interface{}) string {
|
|||
}
|
||||
return message
|
||||
}
|
||||
|
||||
func throwHereBeDragons(arguments ...interface{}) {
|
||||
panic(hereBeDragons(arguments...))
|
||||
}
|
||||
|
||||
func eachPair(list []interface{}, fn func(_0, _1 interface{})) {
|
||||
for len(list) > 0 {
|
||||
var _0, _1 interface{}
|
||||
_0 = list[0]
|
||||
list = list[1:] // Pop off first
|
||||
if len(list) > 0 {
|
||||
_1 = list[0]
|
||||
list = list[1:] // Pop off second
|
||||
}
|
||||
fn(_0, _1)
|
||||
}
|
||||
}
|
||||
|
|
22
otto_test.go
22
otto_test.go
|
@ -1326,6 +1326,7 @@ func TestOttoCall_clone(t *testing.T) {
|
|||
value, err := vm2.Run(`
|
||||
[ abc.toString(), def.toString() ];
|
||||
`)
|
||||
is(err, nil)
|
||||
is(value, `function() { return "abc"; },function() { return "def"; }`)
|
||||
|
||||
_, err = vm2.Run(`
|
||||
|
@ -1336,11 +1337,13 @@ func TestOttoCall_clone(t *testing.T) {
|
|||
value, err = vm1.Run(`
|
||||
[ abc.toString(), def.toString() ];
|
||||
`)
|
||||
is(err, nil)
|
||||
is(value, `function() { return "abc"; },function() { return "def"; }`)
|
||||
|
||||
value, err = vm2.Run(`
|
||||
[ abc.toString(), def.toString() ];
|
||||
`)
|
||||
is(err, nil)
|
||||
is(value, `function() { return "abc"; },function() { return "ghi"; }`)
|
||||
}
|
||||
|
||||
|
@ -1367,6 +1370,7 @@ func TestOttoRun(t *testing.T) {
|
|||
is(value, 4)
|
||||
|
||||
program, err = parser.ParseFile(nil, "", "var abc; if (!abc) abc = 0; abc += 2; abc;", 0)
|
||||
is(err, nil)
|
||||
value, err = vm.Run(program)
|
||||
is(err, nil)
|
||||
is(value, 2)
|
||||
|
@ -1494,7 +1498,7 @@ func TestOttoContext(t *testing.T) {
|
|||
builtins := []string{
|
||||
"escape",
|
||||
"URIError",
|
||||
"RegExp",
|
||||
classRegExp,
|
||||
"ReferenceError",
|
||||
"parseFloat",
|
||||
"parseInt",
|
||||
|
@ -1506,23 +1510,23 @@ func TestOttoContext(t *testing.T) {
|
|||
"isNaN",
|
||||
"unescape",
|
||||
"decodeURI",
|
||||
"Object",
|
||||
"Function",
|
||||
classObject,
|
||||
classFunction,
|
||||
"RangeError",
|
||||
"Error",
|
||||
classError,
|
||||
"get_context",
|
||||
"eval",
|
||||
"Number",
|
||||
classNumber,
|
||||
"Math",
|
||||
"NaN",
|
||||
"Date",
|
||||
"Boolean",
|
||||
classDate,
|
||||
classBoolean,
|
||||
"console",
|
||||
"encodeURI",
|
||||
"EvalError",
|
||||
"Array",
|
||||
classArray,
|
||||
"TypeError",
|
||||
"String",
|
||||
classString,
|
||||
"isFinite",
|
||||
"undefined",
|
||||
}
|
||||
|
|
|
@ -2,9 +2,10 @@ package parser
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/robertkrimen/otto/ast"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/robertkrimen/otto/ast"
|
||||
)
|
||||
|
||||
func checkComments(actual []*ast.Comment, expected []string, position ast.CommentPosition) error {
|
||||
|
@ -31,13 +32,6 @@ func checkComments(actual []*ast.Comment, expected []string, position ast.Commen
|
|||
return nil
|
||||
}
|
||||
|
||||
func displayStatements(statements []ast.Statement) {
|
||||
fmt.Printf("Printing statements (%v)\n", len(statements))
|
||||
for k, v := range statements {
|
||||
fmt.Printf("Type of line %v: %v\n", k, reflect.TypeOf(v))
|
||||
}
|
||||
}
|
||||
|
||||
func displayComments(m ast.CommentMap) {
|
||||
fmt.Printf("Displaying comments:\n")
|
||||
for n, comments := range m {
|
||||
|
@ -404,7 +398,7 @@ t2 = "Nothing happens."
|
|||
is(checkComments((parser.comments.CommentMap)[program.Body[1]], []string{"Test", "Test2"}, ast.LEADING), nil)
|
||||
|
||||
// Misc
|
||||
parser, program = test(`
|
||||
parser, _ = test(`
|
||||
var x = Object.create({y: {
|
||||
},
|
||||
// a
|
||||
|
@ -413,7 +407,7 @@ var x = Object.create({y: {
|
|||
is(parser.comments.CommentMap.Size(), 1)
|
||||
|
||||
// Misc 2
|
||||
parser, program = test(`
|
||||
parser, _ = test(`
|
||||
var x = Object.create({y: {
|
||||
},
|
||||
// a
|
||||
|
@ -818,7 +812,7 @@ if(a) {
|
|||
is(checkComments((parser.comments.CommentMap)[program.Body[0].(*ast.IfStatement).Alternate], []string{"comment"}, ast.TRAILING), nil)
|
||||
|
||||
// If then else pt 8
|
||||
parser, program = test(`
|
||||
parser, _ = test(`
|
||||
if
|
||||
/*comment*/
|
||||
(a) {
|
||||
|
@ -830,7 +824,7 @@ if
|
|||
is(parser.comments.CommentMap.Size(), 1)
|
||||
|
||||
// If then else pt 9
|
||||
parser, program = test(`
|
||||
parser, _ = test(`
|
||||
if
|
||||
(a)
|
||||
/*comment*/{
|
||||
|
@ -842,7 +836,7 @@ if
|
|||
is(parser.comments.CommentMap.Size(), 1)
|
||||
|
||||
// If then else pt 10
|
||||
parser, program = test(`
|
||||
parser, _ = test(`
|
||||
if(a){
|
||||
b
|
||||
}
|
||||
|
@ -971,7 +965,7 @@ while(a) {
|
|||
is(checkComments((parser.comments.CommentMap)[program.Body[0].(*ast.WhileStatement).Body.(*ast.BlockStatement)], []string{"comment"}, ast.FINAL), nil)
|
||||
|
||||
// While pt 8
|
||||
parser, program = test(`
|
||||
parser, _ = test(`
|
||||
while
|
||||
/*comment*/(a) {
|
||||
|
||||
|
@ -980,7 +974,7 @@ while
|
|||
is(parser.comments.CommentMap.Size(), 1)
|
||||
|
||||
// While pt 9
|
||||
parser, program = test(`
|
||||
parser, _ = test(`
|
||||
while
|
||||
(a)
|
||||
/*comment*/{
|
||||
|
@ -1109,7 +1103,7 @@ with(a) {
|
|||
is(checkComments((parser.comments.CommentMap)[program.Body[0].(*ast.WithStatement).Body], []string{"comment"}, ast.TRAILING), nil)
|
||||
|
||||
// With pt 7
|
||||
parser, program = test(`
|
||||
parser, _ = test(`
|
||||
with
|
||||
/*comment*/(a) {
|
||||
}
|
||||
|
@ -1117,7 +1111,7 @@ with
|
|||
is(parser.comments.CommentMap.Size(), 1)
|
||||
|
||||
// With pt 8
|
||||
parser, program = test(`
|
||||
parser, _ = test(`
|
||||
with
|
||||
(a)
|
||||
/*comment*/{
|
||||
|
@ -1176,7 +1170,7 @@ var a, b;
|
|||
is(checkComments((parser.comments.CommentMap)[program], []string{"comment"}, ast.TRAILING), nil)
|
||||
|
||||
// Return
|
||||
parser, program = test(`
|
||||
parser, _ = test(`
|
||||
function f() {
|
||||
/*comment*/return o
|
||||
}
|
||||
|
@ -1356,7 +1350,7 @@ try {
|
|||
is(checkComments((parser.comments.CommentMap)[program.Body[0].(*ast.TryStatement).Finally], []string{"comment"}, ast.LEADING), nil)
|
||||
|
||||
// Switch / comment
|
||||
parser, program = test(`
|
||||
parser, _ = test(`
|
||||
var volvo = 1
|
||||
//comment
|
||||
switch(abra) {
|
||||
|
@ -1365,7 +1359,7 @@ switch(abra) {
|
|||
is(parser.comments.CommentMap.Size(), 1)
|
||||
|
||||
// Switch / comment
|
||||
parser, program = test(`
|
||||
parser, _ = test(`
|
||||
f("string",{
|
||||
key: "val"
|
||||
//comment
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
// This file was AUTOMATICALLY GENERATED by dbg-import (smuggol) for github.com/robertkrimen/dbg
|
||||
|
||||
package parser
|
||||
|
||||
import (
|
||||
Dbg "github.com/robertkrimen/otto/dbg"
|
||||
)
|
||||
|
||||
var dbg, dbgf = Dbg.New()
|
|
@ -11,7 +11,6 @@ import (
|
|||
const (
|
||||
err_UnexpectedToken = "Unexpected token %v"
|
||||
err_UnexpectedEndOfInput = "Unexpected end of input"
|
||||
err_UnexpectedEscape = "Unexpected escape"
|
||||
)
|
||||
|
||||
// UnexpectedNumber: 'Unexpected number',
|
||||
|
@ -70,7 +69,7 @@ func (self Error) Error() string {
|
|||
}
|
||||
|
||||
func (self *_parser) error(place interface{}, msg string, msgValues ...interface{}) *Error {
|
||||
idx := file.Idx(0)
|
||||
var idx file.Idx
|
||||
switch place := place.(type) {
|
||||
case int:
|
||||
idx = self.idxOf(place)
|
||||
|
@ -120,8 +119,7 @@ func (self *_parser) errorUnexpectedToken(tkn token.Token) error {
|
|||
}
|
||||
|
||||
// ErrorList is a list of *Errors.
|
||||
//
|
||||
type ErrorList []*Error
|
||||
type ErrorList []*Error // nolint: errname
|
||||
|
||||
// Add adds an Error with given position and message to an ErrorList.
|
||||
func (self *ErrorList) Add(position file.Position, msg string) {
|
||||
|
|
|
@ -352,7 +352,7 @@ func (self *_parser) parseArrayLiteral() ast.Expression {
|
|||
for self.token != token.RIGHT_BRACKET && self.token != token.EOF {
|
||||
if self.token == token.COMMA {
|
||||
// This kind of comment requires a special empty expression node.
|
||||
empty := &ast.EmptyExpression{self.idx, self.idx}
|
||||
empty := &ast.EmptyExpression{Begin: self.idx, End: self.idx}
|
||||
|
||||
if self.mode&StoreComments != 0 {
|
||||
self.comments.SetExpression(empty)
|
||||
|
|
|
@ -628,14 +628,14 @@ func parseNumberLiteral(literal string) (value interface{}, err error) {
|
|||
// TODO Is Uint okay? What about -MAX_UINT
|
||||
value, err = strconv.ParseInt(literal, 0, 64)
|
||||
if err == nil {
|
||||
return
|
||||
return value, nil
|
||||
}
|
||||
|
||||
parseIntErr := err // Save this first error, just in case
|
||||
|
||||
value, err = strconv.ParseFloat(literal, 64)
|
||||
if err == nil {
|
||||
return
|
||||
return value, nil
|
||||
} else if err.(*strconv.NumError).Err == strconv.ErrRange {
|
||||
// Infinity, etc.
|
||||
return value, nil
|
||||
|
@ -651,7 +651,7 @@ func parseNumberLiteral(literal string) (value interface{}, err error) {
|
|||
for _, chr := range literal {
|
||||
digit := digitValue(chr)
|
||||
if digit >= 16 {
|
||||
goto error
|
||||
return nil, errors.New("Illegal numeric literal")
|
||||
}
|
||||
value = value*16 + float64(digit)
|
||||
}
|
||||
|
@ -659,7 +659,6 @@ func parseNumberLiteral(literal string) (value interface{}, err error) {
|
|||
}
|
||||
}
|
||||
|
||||
error:
|
||||
return nil, errors.New("Illegal numeric literal")
|
||||
}
|
||||
|
||||
|
|
|
@ -854,8 +854,6 @@ func TestParserAST(t *testing.T) {
|
|||
]
|
||||
`)
|
||||
|
||||
return
|
||||
|
||||
test(`
|
||||
if (!abc && abc.jkl(def) && abc[0] === +abc[0] && abc.length < ghi) {
|
||||
}
|
||||
|
|
|
@ -98,9 +98,9 @@ func TestParserErr(t *testing.T) {
|
|||
return program, parser
|
||||
}
|
||||
|
||||
program, parser := test("", nil)
|
||||
test("", nil)
|
||||
|
||||
program, parser = test(`
|
||||
program, parser := test(`
|
||||
var abc;
|
||||
break; do {
|
||||
} while(true);
|
||||
|
@ -523,7 +523,7 @@ func TestParser(t *testing.T) {
|
|||
abc()
|
||||
`, nil)
|
||||
|
||||
program := test("", nil)
|
||||
test("", nil)
|
||||
|
||||
test("//", nil)
|
||||
|
||||
|
@ -541,7 +541,7 @@ func TestParser(t *testing.T) {
|
|||
|
||||
test("new +", "(anonymous): Line 1:5 Unexpected token +")
|
||||
|
||||
program = test(";", nil)
|
||||
program := test(";", nil)
|
||||
is(len(program.Body), 1)
|
||||
is(program.Body[0].(*ast.EmptyStatement).Semicolon, file.Idx(1))
|
||||
|
||||
|
@ -1012,6 +1012,7 @@ func TestPosition(t *testing.T) {
|
|||
|
||||
parser = _newParser("", "this.style", 1, nil)
|
||||
program, err = parser.parse()
|
||||
is(err, nil)
|
||||
node = program.Body[0].(*ast.ExpressionStatement).Expression.(*ast.DotExpression).Left.(*ast.ThisExpression)
|
||||
is(node.Idx0(), file.Idx(1))
|
||||
is(node.Idx1(), file.Idx(5))
|
||||
|
|
|
@ -9,7 +9,6 @@ const (
|
|||
modeEnumerateMask = 0070
|
||||
modeConfigureMask = 0007
|
||||
modeOnMask = 0111
|
||||
modeOffMask = 0000
|
||||
modeSetMask = 0222 // If value is 2, then mode is neither "On" nor "Off"
|
||||
)
|
||||
|
||||
|
|
|
@ -761,11 +761,11 @@ func TestPassthrough(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
type TestDynamicFunctionReturningInterface_MyStruct1 struct{}
|
||||
type TestDynamicFunctionReturningInterface_MyStruct1 struct{} // nolint: errname
|
||||
|
||||
func (m *TestDynamicFunctionReturningInterface_MyStruct1) Error() string { return "MyStruct1" }
|
||||
|
||||
type TestDynamicFunctionReturningInterface_MyStruct2 struct{}
|
||||
type TestDynamicFunctionReturningInterface_MyStruct2 struct{} // nolint: errname
|
||||
|
||||
func (m *TestDynamicFunctionReturningInterface_MyStruct2) Error() string { return "MyStruct2" }
|
||||
|
||||
|
|
|
@ -36,13 +36,13 @@ func TestRegExp(t *testing.T) {
|
|||
result := test(`/(a)?/.exec('b')`, ",")
|
||||
is(result._object().get("0"), "")
|
||||
is(result._object().get("1"), "undefined")
|
||||
is(result._object().get("length"), 2)
|
||||
is(result._object().get(propertyLength), 2)
|
||||
|
||||
result = test(`/(a)?(b)?/.exec('b')`, "b,,b")
|
||||
is(result._object().get("0"), "b")
|
||||
is(result._object().get("1"), "undefined")
|
||||
is(result._object().get("2"), "b")
|
||||
is(result._object().get("length"), 3)
|
||||
is(result._object().get(propertyLength), 3)
|
||||
|
||||
test(`/\u0041/.source`, "\\u0041")
|
||||
test(`/\a/.source`, "\\a")
|
||||
|
|
|
@ -41,7 +41,7 @@ func (a *autoCompleter) Do(line []rune, pos int) ([][]rune, int) {
|
|||
|
||||
if o := r.Object(); o != nil {
|
||||
for _, v := range o.KeysByParent() {
|
||||
l = append(l, v...)
|
||||
l = append(l, v...) // nolint: makezero
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
package otto
|
||||
|
||||
import ()
|
||||
|
||||
type _resultKind int
|
||||
|
||||
const (
|
||||
resultNormal _resultKind = iota
|
||||
_ _resultKind = iota
|
||||
resultReturn
|
||||
resultBreak
|
||||
resultContinue
|
||||
|
|
10
runtime.go
10
runtime.go
|
@ -414,14 +414,14 @@ func (self *_runtime) convertCallParameter(v Value, t reflect.Type) (reflect.Val
|
|||
}
|
||||
case reflect.Slice:
|
||||
if o := v._object(); o != nil {
|
||||
if lv := o.get("length"); lv.IsNumber() {
|
||||
if lv := o.get(propertyLength); lv.IsNumber() {
|
||||
l := lv.number().int64
|
||||
|
||||
s := reflect.MakeSlice(t, int(l), int(l))
|
||||
|
||||
tt := t.Elem()
|
||||
|
||||
if o.class == "Array" {
|
||||
if o.class == classArray {
|
||||
for i := int64(0); i < l; i++ {
|
||||
p, ok := o.property[strconv.FormatInt(i, 10)]
|
||||
if !ok {
|
||||
|
@ -440,7 +440,7 @@ func (self *_runtime) convertCallParameter(v Value, t reflect.Type) (reflect.Val
|
|||
|
||||
s.Index(int(i)).Set(ev)
|
||||
}
|
||||
} else if o.class == "GoArray" {
|
||||
} else if o.class == classGoArray {
|
||||
var gslice bool
|
||||
switch o.value.(type) {
|
||||
case *_goSliceObject:
|
||||
|
@ -504,7 +504,7 @@ func (self *_runtime) convertCallParameter(v Value, t reflect.Type) (reflect.Val
|
|||
return reflect.Zero(t), fmt.Errorf("converting JavaScript values to Go functions with more than one return value is currently not supported")
|
||||
}
|
||||
|
||||
if o := v._object(); o != nil && o.class == "Function" {
|
||||
if o := v._object(); o != nil && o.class == classFunction {
|
||||
return reflect.MakeFunc(t, func(args []reflect.Value) []reflect.Value {
|
||||
l := make([]interface{}, len(args))
|
||||
for i, a := range args {
|
||||
|
@ -531,7 +531,7 @@ func (self *_runtime) convertCallParameter(v Value, t reflect.Type) (reflect.Val
|
|||
}), nil
|
||||
}
|
||||
case reflect.Struct:
|
||||
if o := v._object(); o != nil && o.class == "Object" {
|
||||
if o := v._object(); o != nil && o.class == classObject {
|
||||
s := reflect.New(t)
|
||||
|
||||
for _, k := range o.propertyOrder {
|
||||
|
|
41
script.go
41
script.go
|
@ -86,34 +86,27 @@ func (self *Script) marshalBinary() ([]byte, error) {
|
|||
// will return an error.
|
||||
//
|
||||
// The binary format can change at any time and should be considered unspecified and opaque.
|
||||
//
|
||||
func (self *Script) unmarshalBinary(data []byte) error {
|
||||
func (self *Script) unmarshalBinary(data []byte) (err error) {
|
||||
decoder := gob.NewDecoder(bytes.NewReader(data))
|
||||
err := decoder.Decode(&self.version)
|
||||
if err != nil {
|
||||
goto error
|
||||
defer func() {
|
||||
if err != nil {
|
||||
self.version = ""
|
||||
self.program = nil
|
||||
self.filename = ""
|
||||
self.src = ""
|
||||
}
|
||||
}()
|
||||
if err = decoder.Decode(&self.version); err != nil {
|
||||
return err
|
||||
}
|
||||
if self.version != scriptVersion {
|
||||
err = ErrVersion
|
||||
goto error
|
||||
return ErrVersion
|
||||
}
|
||||
err = decoder.Decode(&self.program)
|
||||
if err != nil {
|
||||
goto error
|
||||
if err = decoder.Decode(&self.program); err != nil {
|
||||
return err
|
||||
}
|
||||
err = decoder.Decode(&self.filename)
|
||||
if err != nil {
|
||||
goto error
|
||||
if err = decoder.Decode(&self.filename); err != nil {
|
||||
return err
|
||||
}
|
||||
err = decoder.Decode(&self.src)
|
||||
if err != nil {
|
||||
goto error
|
||||
}
|
||||
return nil
|
||||
error:
|
||||
self.version = ""
|
||||
self.program = nil
|
||||
self.filename = ""
|
||||
self.src = ""
|
||||
return err
|
||||
return decoder.Decode(&self.src)
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@ var target = map[string]string{
|
|||
// http://api.cdnjs.com/libraries
|
||||
|
||||
func fetch(name, location string) error {
|
||||
response, err := http.Get(location)
|
||||
response, err := http.Get(location) // nolint: noctx
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -110,7 +110,7 @@ func main() {
|
|||
err := func() error {
|
||||
|
||||
if flag.Arg(0) == "fetch" {
|
||||
response, err := http.Get("http://api.cdnjs.com/libraries")
|
||||
response, err := http.Get("http://api.cdnjs.com/libraries") // nolint: noctx
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -166,8 +166,8 @@ func main() {
|
|||
case "parse":
|
||||
fmt.Fprintln(writer, name, "\t| pass (parse)")
|
||||
case "re2":
|
||||
continue
|
||||
fmt.Fprintln(writer, name, "\t| unknown (re2)")
|
||||
continue
|
||||
}
|
||||
} else {
|
||||
fmt.Fprintln(writer, name, "\t| fail")
|
||||
|
|
|
@ -10,6 +10,7 @@ import (
|
|||
)
|
||||
|
||||
func tt(t *testing.T, arguments ...func()) {
|
||||
t.Helper()
|
||||
halt := errors.New("A test was taking too long")
|
||||
timer := time.AfterFunc(20*time.Second, func() {
|
||||
panic(halt)
|
||||
|
|
|
@ -74,7 +74,7 @@ const (
|
|||
COLON // :
|
||||
QUESTION_MARK // ?
|
||||
|
||||
firstKeyword
|
||||
firstKeyword // nolint: deadcode
|
||||
IF
|
||||
IN
|
||||
DO
|
||||
|
@ -108,7 +108,7 @@ const (
|
|||
DEBUGGER
|
||||
|
||||
INSTANCEOF
|
||||
lastKeyword
|
||||
lastKeyword // nolint: deadcode
|
||||
)
|
||||
|
||||
var token2string = [...]string{
|
||||
|
|
|
@ -20,7 +20,7 @@ func (runtime *_runtime) newArgumentsObject(indexOfParameterName []string, stash
|
|||
|
||||
self.prototype = runtime.global.ObjectPrototype
|
||||
|
||||
self.defineProperty("length", toValue_int(length), 0101, false)
|
||||
self.defineProperty(propertyLength, toValue_int(length), 0101, false)
|
||||
|
||||
return self
|
||||
}
|
||||
|
|
|
@ -6,14 +6,14 @@ import (
|
|||
|
||||
func (runtime *_runtime) newArrayObject(length uint32) *_object {
|
||||
self := runtime.newObject()
|
||||
self.class = "Array"
|
||||
self.defineProperty("length", toValue_uint32(length), 0100, false)
|
||||
self.class = classArray
|
||||
self.defineProperty(propertyLength, toValue_uint32(length), 0100, false)
|
||||
self.objectClass = _classArray
|
||||
return self
|
||||
}
|
||||
|
||||
func isArray(object *_object) bool {
|
||||
return object != nil && (object.class == "Array" || object.class == "GoArray")
|
||||
return object != nil && (object.class == classArray || object.class == classGoArray)
|
||||
}
|
||||
|
||||
func objectLength(object *_object) uint32 {
|
||||
|
@ -21,12 +21,12 @@ func objectLength(object *_object) uint32 {
|
|||
return 0
|
||||
}
|
||||
switch object.class {
|
||||
case "Array":
|
||||
return object.get("length").value.(uint32)
|
||||
case "String":
|
||||
return uint32(object.get("length").value.(int))
|
||||
case "GoArray":
|
||||
return uint32(object.get("length").value.(int))
|
||||
case classArray:
|
||||
return object.get(propertyLength).value.(uint32)
|
||||
case classString:
|
||||
return uint32(object.get(propertyLength).value.(int))
|
||||
case classGoArray:
|
||||
return uint32(object.get(propertyLength).value.(int))
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
@ -41,13 +41,13 @@ func arrayUint32(rt *_runtime, value Value) uint32 {
|
|||
}
|
||||
|
||||
func arrayDefineOwnProperty(self *_object, name string, descriptor _property, throw bool) bool {
|
||||
lengthProperty := self.getOwnProperty("length")
|
||||
lengthProperty := self.getOwnProperty(propertyLength)
|
||||
lengthValue, valid := lengthProperty.value.(Value)
|
||||
if !valid {
|
||||
panic("Array.length != Value{}")
|
||||
}
|
||||
length := lengthValue.value.(uint32)
|
||||
if name == "length" {
|
||||
if name == propertyLength {
|
||||
if descriptor.value == nil {
|
||||
return objectDefineOwnProperty(self, name, descriptor, throw)
|
||||
}
|
||||
|
@ -96,7 +96,7 @@ func arrayDefineOwnProperty(self *_object, name string, descriptor _property, th
|
|||
}
|
||||
if index >= int64(length) {
|
||||
lengthProperty.value = toValue_uint32(uint32(index + 1))
|
||||
objectDefineOwnProperty(self, "length", *lengthProperty, false)
|
||||
objectDefineOwnProperty(self, propertyLength, *lengthProperty, false)
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,13 +1,5 @@
|
|||
package otto
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func (runtime *_runtime) newBooleanObject(value Value) *_object {
|
||||
return runtime.newPrimitiveObject("Boolean", toValue_bool(value.bool()))
|
||||
}
|
||||
|
||||
func booleanToString(value bool) string {
|
||||
return strconv.FormatBool(value)
|
||||
return runtime.newPrimitiveObject(classBoolean, toValue_bool(value.bool()))
|
||||
}
|
||||
|
|
15
type_date.go
15
type_date.go
|
@ -84,12 +84,6 @@ func (self *_dateObject) SetTime(time Time.Time) {
|
|||
self.Set(timeToEpoch(time))
|
||||
}
|
||||
|
||||
func epoch2dateObject(epoch float64) _dateObject {
|
||||
date := _dateObject{}
|
||||
date.Set(epoch)
|
||||
return date
|
||||
}
|
||||
|
||||
func (self *_dateObject) Set(epoch float64) {
|
||||
// epoch
|
||||
self.epoch = epochToInteger(epoch)
|
||||
|
@ -135,7 +129,7 @@ func timeToEpoch(time Time.Time) float64 {
|
|||
|
||||
func (runtime *_runtime) newDateObject(epoch float64) *_object {
|
||||
self := runtime.newObject()
|
||||
self.class = "Date"
|
||||
self.class = classDate
|
||||
|
||||
// FIXME This is ugly...
|
||||
date := _dateObject{}
|
||||
|
@ -150,7 +144,7 @@ func (self *_object) dateValue() _dateObject {
|
|||
}
|
||||
|
||||
func dateObjectOf(rt *_runtime, _dateObject *_object) _dateObject {
|
||||
if _dateObject == nil || _dateObject.class != "Date" {
|
||||
if _dateObject == nil || _dateObject.class != classDate {
|
||||
panic(rt.panicTypeError())
|
||||
}
|
||||
return _dateObject.dateValue()
|
||||
|
@ -165,11 +159,6 @@ func dateFromGoMonth(month Time.Month) int {
|
|||
return int(month) - 1
|
||||
}
|
||||
|
||||
// Both JavaScript & Go are 0-based (Sunday == 0)
|
||||
func dateToGoDay(day int) Time.Weekday {
|
||||
return Time.Weekday(day)
|
||||
}
|
||||
|
||||
func dateFromGoDay(day Time.Weekday) int {
|
||||
return int(day)
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package otto
|
||||
|
||||
func (rt *_runtime) newErrorObject(name string, message Value, stackFramesToPop int) *_object {
|
||||
self := rt.newClassObject("Error")
|
||||
self := rt.newClassObject(classError)
|
||||
if message.IsDefined() {
|
||||
msg := message.string()
|
||||
self.defineProperty("message", toValue_string(msg), 0111, false)
|
||||
|
|
|
@ -6,7 +6,7 @@ type _constructFunction func(*_object, []Value) Value
|
|||
// 13.2.2 [[Construct]]
|
||||
func defaultConstruct(fn *_object, argumentList []Value) Value {
|
||||
object := fn.runtime.newObject()
|
||||
object.class = "Object"
|
||||
object.class = classObject
|
||||
|
||||
prototype := fn.get("prototype")
|
||||
if prototype.kind != valueObject {
|
||||
|
@ -38,7 +38,7 @@ type _nativeFunctionObject struct {
|
|||
}
|
||||
|
||||
func (runtime *_runtime) _newNativeFunctionObject(name, file string, line int, native _nativeFunction, length int) *_object {
|
||||
self := runtime.newClassObject("Function")
|
||||
self := runtime.newClassObject(classFunction)
|
||||
self.value = _nativeFunctionObject{
|
||||
name: name,
|
||||
file: file,
|
||||
|
@ -47,7 +47,7 @@ func (runtime *_runtime) _newNativeFunctionObject(name, file string, line int, n
|
|||
construct: defaultConstruct,
|
||||
}
|
||||
self.defineProperty("name", toValue_string(name), 0000, false)
|
||||
self.defineProperty("length", toValue_int(length), 0000, false)
|
||||
self.defineProperty(propertyLength, toValue_int(length), 0000, false)
|
||||
return self
|
||||
}
|
||||
|
||||
|
@ -86,19 +86,19 @@ type _bindFunctionObject struct {
|
|||
}
|
||||
|
||||
func (runtime *_runtime) newBoundFunctionObject(target *_object, this Value, argumentList []Value) *_object {
|
||||
self := runtime.newClassObject("Function")
|
||||
self := runtime.newClassObject(classFunction)
|
||||
self.value = _bindFunctionObject{
|
||||
target: target,
|
||||
this: this,
|
||||
argumentList: argumentList,
|
||||
}
|
||||
length := int(toInt32(target.get("length")))
|
||||
length := int(toInt32(target.get(propertyLength)))
|
||||
length -= len(argumentList)
|
||||
if length < 0 {
|
||||
length = 0
|
||||
}
|
||||
self.defineProperty("name", toValue_string("bound "+target.get("name").String()), 0000, false)
|
||||
self.defineProperty("length", toValue_int(length), 0000, false)
|
||||
self.defineProperty(propertyLength, toValue_int(length), 0000, false)
|
||||
self.defineProperty("caller", Value{}, 0000, false) // TODO Should throw a TypeError
|
||||
self.defineProperty("arguments", Value{}, 0000, false) // TODO Should throw a TypeError
|
||||
return self
|
||||
|
@ -127,13 +127,13 @@ type _nodeFunctionObject struct {
|
|||
}
|
||||
|
||||
func (runtime *_runtime) newNodeFunctionObject(node *_nodeFunctionLiteral, stash _stash) *_object {
|
||||
self := runtime.newClassObject("Function")
|
||||
self := runtime.newClassObject(classFunction)
|
||||
self.value = _nodeFunctionObject{
|
||||
node: node,
|
||||
stash: stash,
|
||||
}
|
||||
self.defineProperty("name", toValue_string(node.name), 0000, false)
|
||||
self.defineProperty("length", toValue_int(len(node.parameterList)), 0000, false)
|
||||
self.defineProperty(propertyLength, toValue_int(len(node.parameterList)), 0000, false)
|
||||
self.defineOwnProperty("caller", _property{
|
||||
value: _propertyGetSet{
|
||||
runtime.newNativeFunction("get", "internal", 0, func(fc FunctionCall) Value {
|
||||
|
|
|
@ -7,7 +7,7 @@ import (
|
|||
|
||||
func (runtime *_runtime) newGoArrayObject(value reflect.Value) *_object {
|
||||
self := runtime.newObject()
|
||||
self.class = "GoArray"
|
||||
self.class = classGoArray
|
||||
self.objectClass = _classGoArray
|
||||
self.value = _newGoArrayObject(value)
|
||||
return self
|
||||
|
@ -72,7 +72,7 @@ func (self _goArrayObject) setValue(index int64, value Value) bool {
|
|||
|
||||
func goArrayGetOwnProperty(self *_object, name string) *_property {
|
||||
// length
|
||||
if name == "length" {
|
||||
if name == propertyLength {
|
||||
return &_property{
|
||||
value: toValue(reflect.Indirect(self.value.(*_goArrayObject).value).Len()),
|
||||
mode: 0,
|
||||
|
@ -118,7 +118,7 @@ func goArrayEnumerate(self *_object, all bool, each func(string) bool) {
|
|||
}
|
||||
|
||||
func goArrayDefineOwnProperty(self *_object, name string, descriptor _property, throw bool) bool {
|
||||
if name == "length" {
|
||||
if name == propertyLength {
|
||||
return self.runtime.typeErrorResult(throw)
|
||||
} else if index := stringToArrayIndex(name); index >= 0 {
|
||||
object := self.value.(*_goArrayObject)
|
||||
|
@ -134,7 +134,7 @@ func goArrayDefineOwnProperty(self *_object, name string, descriptor _property,
|
|||
|
||||
func goArrayDelete(self *_object, name string, throw bool) bool {
|
||||
// length
|
||||
if name == "length" {
|
||||
if name == propertyLength {
|
||||
return self.runtime.typeErrorResult(throw)
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ import (
|
|||
|
||||
func (runtime *_runtime) newGoMapObject(value reflect.Value) *_object {
|
||||
self := runtime.newObject()
|
||||
self.class = "Object" // TODO Should this be something else?
|
||||
self.class = classObject // TODO Should this be something else?
|
||||
self.objectClass = _classGoMap
|
||||
self.value = _newGoMapObject(value)
|
||||
return self
|
||||
|
|
|
@ -7,7 +7,7 @@ import (
|
|||
|
||||
func (runtime *_runtime) newGoSliceObject(value reflect.Value) *_object {
|
||||
self := runtime.newObject()
|
||||
self.class = "GoArray" // TODO GoSlice?
|
||||
self.class = classGoArray // TODO GoSlice?
|
||||
self.objectClass = _classGoSlice
|
||||
self.value = _newGoSliceObject(value)
|
||||
return self
|
||||
|
@ -46,7 +46,7 @@ func (self _goSliceObject) setValue(index int64, value Value) bool {
|
|||
|
||||
func goSliceGetOwnProperty(self *_object, name string) *_property {
|
||||
// length
|
||||
if name == "length" {
|
||||
if name == propertyLength {
|
||||
return &_property{
|
||||
value: toValue(self.value.(*_goSliceObject).value.Len()),
|
||||
mode: 0,
|
||||
|
@ -93,7 +93,7 @@ func goSliceEnumerate(self *_object, all bool, each func(string) bool) {
|
|||
}
|
||||
|
||||
func goSliceDefineOwnProperty(self *_object, name string, descriptor _property, throw bool) bool {
|
||||
if name == "length" {
|
||||
if name == propertyLength {
|
||||
return self.runtime.typeErrorResult(throw)
|
||||
} else if index := stringToArrayIndex(name); index >= 0 {
|
||||
if self.value.(*_goSliceObject).setValue(index, descriptor.value.(Value)) {
|
||||
|
|
|
@ -15,7 +15,7 @@ import (
|
|||
|
||||
func (runtime *_runtime) newGoStructObject(value reflect.Value) *_object {
|
||||
self := runtime.newObject()
|
||||
self.class = "Object" // TODO Should this be something else?
|
||||
self.class = classObject // TODO Should this be something else?
|
||||
self.objectClass = _classGoStruct
|
||||
self.value = _newGoStructObject(value)
|
||||
return self
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
package otto
|
||||
|
||||
func (runtime *_runtime) newNumberObject(value Value) *_object {
|
||||
return runtime.newPrimitiveObject("Number", value.numberValue())
|
||||
return runtime.newPrimitiveObject(classNumber, value.numberValue())
|
||||
}
|
||||
|
|
|
@ -54,15 +54,6 @@ func (self *_propertyReference) delete() bool {
|
|||
return self.base.delete(self.name, self.strict)
|
||||
}
|
||||
|
||||
// ArgumentReference
|
||||
|
||||
func newArgumentReference(runtime *_runtime, base *_object, name string, strict bool, at _at) *_propertyReference {
|
||||
if base == nil {
|
||||
panic(hereBeDragons())
|
||||
}
|
||||
return newPropertyReference(runtime, base, name, strict, at)
|
||||
}
|
||||
|
||||
type _stashReference struct {
|
||||
name string
|
||||
strict bool
|
||||
|
|
|
@ -19,7 +19,7 @@ type _regExpObject struct {
|
|||
|
||||
func (runtime *_runtime) newRegExpObject(pattern string, flags string) *_object {
|
||||
self := runtime.newObject()
|
||||
self.class = "RegExp"
|
||||
self.class = classRegExp
|
||||
|
||||
global := false
|
||||
ignoreCase := false
|
||||
|
@ -85,7 +85,7 @@ func (self *_object) regExpValue() _regExpObject {
|
|||
}
|
||||
|
||||
func execRegExp(this *_object, target string) (match bool, result []int) {
|
||||
if this.class != "RegExp" {
|
||||
if this.class != classRegExp {
|
||||
panic(this.runtime.panicTypeError("Calling RegExp.exec on a non-RegExp object"))
|
||||
}
|
||||
lastIndex := this.get("lastIndex").number().int64
|
||||
|
|
|
@ -72,8 +72,8 @@ func stringAt(str _stringObject, index int) rune {
|
|||
func (runtime *_runtime) newStringObject(value Value) *_object {
|
||||
str := _newStringObject(value.string())
|
||||
|
||||
self := runtime.newClassObject("String")
|
||||
self.defineProperty("length", toValue_int(str.Length()), 0, false)
|
||||
self := runtime.newClassObject(classString)
|
||||
self.defineProperty(propertyLength, toValue_int(str.Length()), 0, false)
|
||||
self.objectClass = _classString
|
||||
self.value = str
|
||||
return self
|
||||
|
|
72
value.go
72
value.go
|
@ -193,7 +193,7 @@ func (value Value) IsFunction() bool {
|
|||
if value.kind != valueObject {
|
||||
return false
|
||||
}
|
||||
return value.value.(*_object).class == "Function"
|
||||
return value.value.(*_object).class == classFunction
|
||||
}
|
||||
|
||||
// Class will return the class string of the value or the empty string if value is not an object.
|
||||
|
@ -227,42 +227,42 @@ func (value Value) isStringObject() bool {
|
|||
if value.kind != valueObject {
|
||||
return false
|
||||
}
|
||||
return value.value.(*_object).class == "String"
|
||||
return value.value.(*_object).class == classString
|
||||
}
|
||||
|
||||
func (value Value) isBooleanObject() bool {
|
||||
if value.kind != valueObject {
|
||||
return false
|
||||
}
|
||||
return value.value.(*_object).class == "Boolean"
|
||||
return value.value.(*_object).class == classBoolean
|
||||
}
|
||||
|
||||
func (value Value) isNumberObject() bool {
|
||||
if value.kind != valueObject {
|
||||
return false
|
||||
}
|
||||
return value.value.(*_object).class == "Number"
|
||||
return value.value.(*_object).class == classNumber
|
||||
}
|
||||
|
||||
func (value Value) isDate() bool {
|
||||
if value.kind != valueObject {
|
||||
return false
|
||||
}
|
||||
return value.value.(*_object).class == "Date"
|
||||
return value.value.(*_object).class == classDate
|
||||
}
|
||||
|
||||
func (value Value) isRegExp() bool {
|
||||
if value.kind != valueObject {
|
||||
return false
|
||||
}
|
||||
return value.value.(*_object).class == "RegExp"
|
||||
return value.value.(*_object).class == classRegExp
|
||||
}
|
||||
|
||||
func (value Value) isError() bool {
|
||||
if value.kind != valueObject {
|
||||
return false
|
||||
}
|
||||
return value.value.(*_object).class == "Error"
|
||||
return value.value.(*_object).class == classError
|
||||
}
|
||||
|
||||
// ---
|
||||
|
@ -503,14 +503,6 @@ var (
|
|||
__NegativeZero__ float64 = math.Float64frombits(0 | (1 << 63))
|
||||
)
|
||||
|
||||
func positiveInfinity() float64 {
|
||||
return __PositiveInfinity__
|
||||
}
|
||||
|
||||
func negativeInfinity() float64 {
|
||||
return __NegativeInfinity__
|
||||
}
|
||||
|
||||
func positiveZero() float64 {
|
||||
return __PositiveZero__
|
||||
}
|
||||
|
@ -569,62 +561,60 @@ func sameValue(x Value, y Value) bool {
|
|||
if x.kind != y.kind {
|
||||
return false
|
||||
}
|
||||
result := false
|
||||
|
||||
switch x.kind {
|
||||
case valueUndefined, valueNull:
|
||||
result = true
|
||||
return true
|
||||
case valueNumber:
|
||||
x := x.float64()
|
||||
y := y.float64()
|
||||
if math.IsNaN(x) && math.IsNaN(y) {
|
||||
result = true
|
||||
} else {
|
||||
result = x == y
|
||||
if result && x == 0 {
|
||||
// Since +0 != -0
|
||||
result = math.Signbit(x) == math.Signbit(y)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
if x == y {
|
||||
if x == 0 {
|
||||
// Since +0 != -0
|
||||
return math.Signbit(x) == math.Signbit(y)
|
||||
}
|
||||
return true
|
||||
}
|
||||
return false
|
||||
case valueString:
|
||||
result = x.string() == y.string()
|
||||
return x.string() == y.string()
|
||||
case valueBoolean:
|
||||
result = x.bool() == y.bool()
|
||||
return x.bool() == y.bool()
|
||||
case valueObject:
|
||||
result = x._object() == y._object()
|
||||
return x._object() == y._object()
|
||||
default:
|
||||
panic(hereBeDragons())
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func strictEqualityComparison(x Value, y Value) bool {
|
||||
if x.kind != y.kind {
|
||||
return false
|
||||
}
|
||||
result := false
|
||||
|
||||
switch x.kind {
|
||||
case valueUndefined, valueNull:
|
||||
result = true
|
||||
return true
|
||||
case valueNumber:
|
||||
x := x.float64()
|
||||
y := y.float64()
|
||||
if math.IsNaN(x) && math.IsNaN(y) {
|
||||
result = false
|
||||
} else {
|
||||
result = x == y
|
||||
return false
|
||||
}
|
||||
return x == y
|
||||
case valueString:
|
||||
result = x.string() == y.string()
|
||||
return x.string() == y.string()
|
||||
case valueBoolean:
|
||||
result = x.bool() == y.bool()
|
||||
return x.bool() == y.bool()
|
||||
case valueObject:
|
||||
result = x._object() == y._object()
|
||||
return x._object() == y._object()
|
||||
default:
|
||||
panic(hereBeDragons())
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// Export will attempt to convert the value to a Go representation
|
||||
|
@ -676,9 +666,9 @@ func (self Value) export() interface{} {
|
|||
case *_goSliceObject:
|
||||
return value.value.Interface()
|
||||
}
|
||||
if object.class == "Array" {
|
||||
if object.class == classArray {
|
||||
result := make([]interface{}, 0)
|
||||
lengthValue := object.get("length")
|
||||
lengthValue := object.get(propertyLength)
|
||||
length := lengthValue.value.(uint32)
|
||||
kind := reflect.Invalid
|
||||
state := 0
|
||||
|
|
|
@ -85,37 +85,17 @@ func (value Value) float64() float64 {
|
|||
}
|
||||
|
||||
const (
|
||||
float_2_64 float64 = 18446744073709551616.0
|
||||
float_2_63 float64 = 9223372036854775808.0
|
||||
float_2_32 float64 = 4294967296.0
|
||||
float_2_31 float64 = 2147483648.0
|
||||
float_2_16 float64 = 65536.0
|
||||
integer_2_32 int64 = 4294967296
|
||||
integer_2_31 int64 = 2146483648
|
||||
sqrt1_2 float64 = math.Sqrt2 / 2
|
||||
float_2_32 float64 = 4294967296.0
|
||||
float_2_31 float64 = 2147483648.0
|
||||
float_2_16 float64 = 65536.0
|
||||
sqrt1_2 float64 = math.Sqrt2 / 2
|
||||
)
|
||||
|
||||
const (
|
||||
maxInt8 = math.MaxInt8
|
||||
minInt8 = math.MinInt8
|
||||
maxInt16 = math.MaxInt16
|
||||
minInt16 = math.MinInt16
|
||||
maxInt32 = math.MaxInt32
|
||||
minInt32 = math.MinInt32
|
||||
maxInt64 = math.MaxInt64
|
||||
minInt64 = math.MinInt64
|
||||
maxUint8 = math.MaxUint8
|
||||
maxUint16 = math.MaxUint16
|
||||
maxUint32 = math.MaxUint32
|
||||
maxUint64 = math.MaxUint64
|
||||
maxUint = ^uint(0)
|
||||
minUint = 0
|
||||
maxInt = int(^uint(0) >> 1)
|
||||
minInt = -maxInt - 1
|
||||
|
||||
// int64
|
||||
int64_maxInt int64 = int64(maxInt)
|
||||
int64_minInt int64 = int64(minInt)
|
||||
int64_maxInt8 int64 = math.MaxInt8
|
||||
int64_minInt8 int64 = math.MinInt8
|
||||
int64_maxInt16 int64 = math.MaxInt16
|
||||
|
@ -129,9 +109,7 @@ const (
|
|||
// float64
|
||||
float_maxInt float64 = float64(int(^uint(0) >> 1))
|
||||
float_minInt float64 = float64(int(-maxInt - 1))
|
||||
float_minUint float64 = float64(0)
|
||||
float_maxUint float64 = float64(uint(^uint(0)))
|
||||
float_minUint64 float64 = float64(0)
|
||||
float_maxUint64 float64 = math.MaxUint64
|
||||
float_maxInt64 float64 = math.MaxInt64
|
||||
float_minInt64 float64 = math.MinInt64
|
||||
|
@ -220,7 +198,7 @@ func (value Value) number() (number _number) {
|
|||
return
|
||||
}
|
||||
|
||||
integer := float64(0)
|
||||
var integer float64
|
||||
if float > 0 {
|
||||
integer = math.Floor(float)
|
||||
} else {
|
||||
|
|
|
@ -1,9 +1,5 @@
|
|||
package otto
|
||||
|
||||
func toStringPrimitive(value Value) Value {
|
||||
return _toPrimitive(value, defaultValueHintString)
|
||||
}
|
||||
|
||||
func toNumberPrimitive(value Value) Value {
|
||||
return _toPrimitive(value, defaultValueHintNumber)
|
||||
}
|
||||
|
|
|
@ -253,14 +253,14 @@ func TestExport(t *testing.T) {
|
|||
3.1459,
|
||||
[]interface{}{true, false, 0, 3.1459, "abc"},
|
||||
map[string]interface{}{
|
||||
"Boolean": true,
|
||||
"Number": 3.1459,
|
||||
"String": "abc",
|
||||
"Array": []interface{}{false, 0, "", nil},
|
||||
"Object": map[string]interface{}{
|
||||
"Boolean": false,
|
||||
"Number": 0,
|
||||
"String": "def",
|
||||
classBoolean: true,
|
||||
classNumber: 3.1459,
|
||||
classString: "abc",
|
||||
classArray: []interface{}{false, 0, "", nil},
|
||||
classObject: map[string]interface{}{
|
||||
classBoolean: false,
|
||||
classNumber: 0,
|
||||
classString: "def",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user