mirror of
https://github.com/robertkrimen/otto.git
synced 2025-12-24 12:58:05 +08:00
chore: improve error messages (#482)
Improve error messages so we don't just get TypeError with no clue what the issue was.
This commit is contained in:
1
.github/workflows/test-lint.yml
vendored
1
.github/workflows/test-lint.yml
vendored
@@ -25,6 +25,7 @@ jobs:
|
||||
- name: Validate go mod / generate
|
||||
run: |
|
||||
go mod tidy
|
||||
go install golang.org/x/tools/cmd/stringer@latest
|
||||
go generate ./...
|
||||
git --no-pager diff && [[ 0 -eq $(git status --porcelain | wc -l) ]]
|
||||
|
||||
|
||||
@@ -111,7 +111,7 @@ func TestArray_toLocaleString(t *testing.T) {
|
||||
|
||||
test(`raise:
|
||||
[ { toLocaleString: undefined } ].toLocaleString();
|
||||
`, "TypeError")
|
||||
`, `TypeError: Array.toLocaleString index[0] "undefined" is not callable`)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -429,9 +429,9 @@ func TestArray_every(t *testing.T) {
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test(`raise: [].every()`, "TypeError")
|
||||
test(`raise: [].every()`, `TypeError: Array.every argument "undefined" is not callable`)
|
||||
|
||||
test(`raise: [].every("abc")`, "TypeError")
|
||||
test(`raise: [].every("abc")`, `TypeError: Array.every argument "abc" is not callable`)
|
||||
|
||||
test(`[].every(function() { return false })`, true)
|
||||
|
||||
@@ -479,7 +479,7 @@ func TestArray_some(t *testing.T) {
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test(`raise: [].some("abc")`, "TypeError")
|
||||
test(`raise: [].some("abc")`, `TypeError: Array.some "abc" if not callable`)
|
||||
|
||||
test(`[].some(function() { return true })`, false)
|
||||
|
||||
@@ -521,7 +521,7 @@ func TestArray_forEach(t *testing.T) {
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test(`raise: [].forEach("abc")`, "TypeError")
|
||||
test(`raise: [].forEach("abc")`, `TypeError: Array.foreach "abc" if not callable`)
|
||||
|
||||
test(`
|
||||
var abc = 0;
|
||||
@@ -594,7 +594,7 @@ func TestArray_map(t *testing.T) {
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test(`raise: [].map("abc")`, "TypeError")
|
||||
test(`raise: [].map("abc")`, `TypeError: Array.foreach "abc" if not callable`)
|
||||
|
||||
test(`[].map(function() { return 1 }).length`, 0)
|
||||
|
||||
@@ -626,7 +626,7 @@ func TestArray_filter(t *testing.T) {
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test(`raise: [].filter("abc")`, "TypeError")
|
||||
test(`raise: [].filter("abc")`, `TypeError: Array.filter "abc" if not callable`)
|
||||
|
||||
test(`[].filter(function() { return 1 }).length`, 0)
|
||||
|
||||
@@ -640,9 +640,9 @@ func TestArray_reduce(t *testing.T) {
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test(`raise: [].reduce("abc")`, "TypeError")
|
||||
test(`raise: [].reduce("abc")`, `TypeError: Array.reduce "abc" if not callable`)
|
||||
|
||||
test(`raise: [].reduce(function() {})`, "TypeError")
|
||||
test(`raise: [].reduce(function() {})`, `TypeError: Array.reduce "function() {}" if not callable`)
|
||||
|
||||
test(`[].reduce(function() {}, 0)`, 0)
|
||||
|
||||
@@ -660,9 +660,9 @@ func TestArray_reduceRight(t *testing.T) {
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test(`raise: [].reduceRight("abc")`, "TypeError")
|
||||
test(`raise: [].reduceRight("abc")`, `TypeError: Array.reduceRight "abc" if not callable`)
|
||||
|
||||
test(`raise: [].reduceRight(function() {})`, "TypeError")
|
||||
test(`raise: [].reduceRight(function() {})`, `TypeError: Array.reduceRight "function() {}" if not callable`)
|
||||
|
||||
test(`[].reduceRight(function() {}, 0)`, 0)
|
||||
|
||||
@@ -697,7 +697,7 @@ func TestArray_defineOwnProperty(t *testing.T) {
|
||||
Object.defineProperty(abc, "length", {
|
||||
writable: true
|
||||
});
|
||||
`, "TypeError")
|
||||
`, `TypeError: Object.DefineOwnProperty: property not configurable or writeable and descriptor not writeable`)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ func builtinArrayToLocaleString(call FunctionCall) Value {
|
||||
obj := call.runtime.toObject(value)
|
||||
toLocaleString := obj.get("toLocaleString")
|
||||
if !toLocaleString.isCallable() {
|
||||
panic(call.runtime.panicTypeError())
|
||||
panic(call.runtime.panicTypeError("Array.toLocaleString index[%d] %q is not callable", index, toLocaleString))
|
||||
}
|
||||
stringValue = toLocaleString.call(call.runtime, objectValue(obj)).string()
|
||||
}
|
||||
@@ -457,7 +457,7 @@ func builtinArraySort(call FunctionCall) Value {
|
||||
compare := compareValue.object()
|
||||
if compareValue.IsUndefined() {
|
||||
} else if !compareValue.isCallable() {
|
||||
panic(call.runtime.panicTypeError())
|
||||
panic(call.runtime.panicTypeError("Array.sort value %q is not callable", compareValue))
|
||||
}
|
||||
if length > 1 {
|
||||
arraySortQuickSort(thisObject, 0, length-1, compare)
|
||||
@@ -541,7 +541,7 @@ func builtinArrayEvery(call FunctionCall) Value {
|
||||
}
|
||||
return trueValue
|
||||
}
|
||||
panic(call.runtime.panicTypeError())
|
||||
panic(call.runtime.panicTypeError("Array.every argument %q is not callable", call.Argument(0)))
|
||||
}
|
||||
|
||||
func builtinArraySome(call FunctionCall) Value {
|
||||
@@ -559,7 +559,7 @@ func builtinArraySome(call FunctionCall) Value {
|
||||
}
|
||||
return falseValue
|
||||
}
|
||||
panic(call.runtime.panicTypeError())
|
||||
panic(call.runtime.panicTypeError("Array.some %q if not callable", call.Argument(0)))
|
||||
}
|
||||
|
||||
func builtinArrayForEach(call FunctionCall) Value {
|
||||
@@ -575,7 +575,7 @@ func builtinArrayForEach(call FunctionCall) Value {
|
||||
}
|
||||
return Value{}
|
||||
}
|
||||
panic(call.runtime.panicTypeError())
|
||||
panic(call.runtime.panicTypeError("Array.foreach %q if not callable", call.Argument(0)))
|
||||
}
|
||||
|
||||
func builtinArrayMap(call FunctionCall) Value {
|
||||
@@ -594,7 +594,7 @@ func builtinArrayMap(call FunctionCall) Value {
|
||||
}
|
||||
return objectValue(call.runtime.newArrayOf(values))
|
||||
}
|
||||
panic(call.runtime.panicTypeError())
|
||||
panic(call.runtime.panicTypeError("Array.foreach %q if not callable", call.Argument(0)))
|
||||
}
|
||||
|
||||
func builtinArrayFilter(call FunctionCall) Value {
|
||||
@@ -614,7 +614,7 @@ func builtinArrayFilter(call FunctionCall) Value {
|
||||
}
|
||||
return objectValue(call.runtime.newArrayOf(values))
|
||||
}
|
||||
panic(call.runtime.panicTypeError())
|
||||
panic(call.runtime.panicTypeError("Array.filter %q if not callable", call.Argument(0)))
|
||||
}
|
||||
|
||||
func builtinArrayReduce(call FunctionCall) Value {
|
||||
@@ -647,7 +647,7 @@ func builtinArrayReduce(call FunctionCall) Value {
|
||||
return accumulator
|
||||
}
|
||||
}
|
||||
panic(call.runtime.panicTypeError())
|
||||
panic(call.runtime.panicTypeError("Array.reduce %q if not callable", call.Argument(0)))
|
||||
}
|
||||
|
||||
func builtinArrayReduceRight(call FunctionCall) Value {
|
||||
@@ -679,5 +679,5 @@ func builtinArrayReduceRight(call FunctionCall) Value {
|
||||
return accumulator
|
||||
}
|
||||
}
|
||||
panic(call.runtime.panicTypeError())
|
||||
panic(call.runtime.panicTypeError("Array.reduceRight %q if not callable", call.Argument(0)))
|
||||
}
|
||||
|
||||
@@ -81,7 +81,7 @@ func builtinDateToJSON(call FunctionCall) Value {
|
||||
toISOString := obj.get("toISOString")
|
||||
if !toISOString.isCallable() {
|
||||
// FIXME
|
||||
panic(call.runtime.panicTypeError())
|
||||
panic(call.runtime.panicTypeError("Date.toJSON toISOString %q is not callable", toISOString))
|
||||
}
|
||||
return toISOString.call(call.runtime, objectValue(obj), []Value{})
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ func builtinNewError(obj *object, argumentList []Value) Value {
|
||||
func builtinErrorToString(call FunctionCall) Value {
|
||||
thisObject := call.thisObject()
|
||||
if thisObject == nil {
|
||||
panic(call.runtime.panicTypeError())
|
||||
panic(call.runtime.panicTypeError("Error.toString is nil"))
|
||||
}
|
||||
|
||||
name := classErrorName
|
||||
|
||||
@@ -58,14 +58,14 @@ func builtinFunctionToString(call FunctionCall) Value {
|
||||
return stringValue(fn.node.source)
|
||||
case bindFunctionObject:
|
||||
return stringValue("function () { [native code] }")
|
||||
default:
|
||||
panic(call.runtime.panicTypeError("Function.toString unknown type %T", obj.value))
|
||||
}
|
||||
|
||||
panic(call.runtime.panicTypeError("Function.toString()"))
|
||||
}
|
||||
|
||||
func builtinFunctionApply(call FunctionCall) Value {
|
||||
if !call.This.isCallable() {
|
||||
panic(call.runtime.panicTypeError())
|
||||
panic(call.runtime.panicTypeError("Function.apply %q is not callable", call.This))
|
||||
}
|
||||
this := call.Argument(0)
|
||||
if this.IsUndefined() {
|
||||
@@ -78,7 +78,7 @@ func builtinFunctionApply(call FunctionCall) Value {
|
||||
return call.thisObject().call(this, nil, false, nativeFrame)
|
||||
case valueObject:
|
||||
default:
|
||||
panic(call.runtime.panicTypeError())
|
||||
panic(call.runtime.panicTypeError("Function.apply unknown type %T for second argument"))
|
||||
}
|
||||
|
||||
arrayObject := argumentList.object()
|
||||
@@ -93,7 +93,7 @@ func builtinFunctionApply(call FunctionCall) Value {
|
||||
|
||||
func builtinFunctionCall(call FunctionCall) Value {
|
||||
if !call.This.isCallable() {
|
||||
panic(call.runtime.panicTypeError())
|
||||
panic(call.runtime.panicTypeError("Function.call %q is not callable", call.This))
|
||||
}
|
||||
thisObject := call.thisObject()
|
||||
this := call.Argument(0)
|
||||
@@ -110,7 +110,7 @@ func builtinFunctionCall(call FunctionCall) Value {
|
||||
func builtinFunctionBind(call FunctionCall) Value {
|
||||
target := call.This
|
||||
if !target.isCallable() {
|
||||
panic(call.runtime.panicTypeError())
|
||||
panic(call.runtime.panicTypeError("Function.bind %q is not callable", call.This))
|
||||
}
|
||||
targetObject := target.object()
|
||||
|
||||
|
||||
@@ -180,12 +180,12 @@ func builtinJSONStringify(call FunctionCall) Value {
|
||||
}
|
||||
valueJSON, err := json.Marshal(value)
|
||||
if err != nil {
|
||||
panic(call.runtime.panicTypeError(err.Error()))
|
||||
panic(call.runtime.panicTypeError("JSON.stringify marshal: %s", err))
|
||||
}
|
||||
if ctx.gap != "" {
|
||||
valueJSON1 := bytes.Buffer{}
|
||||
if err = json.Indent(&valueJSON1, valueJSON, "", ctx.gap); err != nil {
|
||||
panic(call.runtime.panicTypeError(err.Error()))
|
||||
panic(call.runtime.panicTypeError("JSON.stringify indent: %s", err))
|
||||
}
|
||||
valueJSON = valueJSON1.Bytes()
|
||||
}
|
||||
|
||||
@@ -81,7 +81,7 @@ func builtinObjectToString(call FunctionCall) Value {
|
||||
func builtinObjectToLocaleString(call FunctionCall) Value {
|
||||
toString := call.thisObject().get("toString")
|
||||
if !toString.isCallable() {
|
||||
panic(call.runtime.panicTypeError())
|
||||
panic(call.runtime.panicTypeError("Object.toLocaleString %q is not callable", toString))
|
||||
}
|
||||
return toString.call(call.runtime, call.This)
|
||||
}
|
||||
@@ -90,7 +90,7 @@ func builtinObjectGetPrototypeOf(call FunctionCall) Value {
|
||||
val := call.Argument(0)
|
||||
obj := val.object()
|
||||
if obj == nil {
|
||||
panic(call.runtime.panicTypeError())
|
||||
panic(call.runtime.panicTypeError("Object.GetPrototypeOf is nil"))
|
||||
}
|
||||
|
||||
if obj.prototype == nil {
|
||||
@@ -104,7 +104,7 @@ func builtinObjectGetOwnPropertyDescriptor(call FunctionCall) Value {
|
||||
val := call.Argument(0)
|
||||
obj := val.object()
|
||||
if obj == nil {
|
||||
panic(call.runtime.panicTypeError())
|
||||
panic(call.runtime.panicTypeError("Object.GetOwnPropertyDescriptor is nil"))
|
||||
}
|
||||
|
||||
name := call.Argument(1).string()
|
||||
@@ -119,7 +119,7 @@ func builtinObjectDefineProperty(call FunctionCall) Value {
|
||||
val := call.Argument(0)
|
||||
obj := val.object()
|
||||
if obj == nil {
|
||||
panic(call.runtime.panicTypeError())
|
||||
panic(call.runtime.panicTypeError("Object.DefineProperty is nil"))
|
||||
}
|
||||
name := call.Argument(1).string()
|
||||
descriptor := toPropertyDescriptor(call.runtime, call.Argument(2))
|
||||
@@ -131,7 +131,7 @@ func builtinObjectDefineProperties(call FunctionCall) Value {
|
||||
val := call.Argument(0)
|
||||
obj := val.object()
|
||||
if obj == nil {
|
||||
panic(call.runtime.panicTypeError())
|
||||
panic(call.runtime.panicTypeError("Object.DefineProperties is nil"))
|
||||
}
|
||||
|
||||
properties := call.runtime.toObject(call.Argument(1))
|
||||
@@ -147,7 +147,7 @@ func builtinObjectDefineProperties(call FunctionCall) Value {
|
||||
func builtinObjectCreate(call FunctionCall) Value {
|
||||
prototypeValue := call.Argument(0)
|
||||
if !prototypeValue.IsNull() && !prototypeValue.IsObject() {
|
||||
panic(call.runtime.panicTypeError())
|
||||
panic(call.runtime.panicTypeError("Object.Create is nil"))
|
||||
}
|
||||
|
||||
obj := call.runtime.newObject()
|
||||
@@ -171,17 +171,16 @@ func builtinObjectIsExtensible(call FunctionCall) Value {
|
||||
if obj := val.object(); obj != nil {
|
||||
return boolValue(obj.extensible)
|
||||
}
|
||||
panic(call.runtime.panicTypeError())
|
||||
panic(call.runtime.panicTypeError("Object.IsExtensible is nil"))
|
||||
}
|
||||
|
||||
func builtinObjectPreventExtensions(call FunctionCall) Value {
|
||||
val := call.Argument(0)
|
||||
if obj := val.object(); obj != nil {
|
||||
obj.extensible = false
|
||||
} else {
|
||||
panic(call.runtime.panicTypeError())
|
||||
return val
|
||||
}
|
||||
return val
|
||||
panic(call.runtime.panicTypeError("Object.PreventExtensions is nil"))
|
||||
}
|
||||
|
||||
func builtinObjectIsSealed(call FunctionCall) Value {
|
||||
@@ -200,7 +199,7 @@ func builtinObjectIsSealed(call FunctionCall) Value {
|
||||
})
|
||||
return boolValue(result)
|
||||
}
|
||||
panic(call.runtime.panicTypeError())
|
||||
panic(call.runtime.panicTypeError("Object.IsSealed is nil"))
|
||||
}
|
||||
|
||||
func builtinObjectSeal(call FunctionCall) Value {
|
||||
@@ -214,10 +213,9 @@ func builtinObjectSeal(call FunctionCall) Value {
|
||||
return true
|
||||
})
|
||||
obj.extensible = false
|
||||
} else {
|
||||
panic(call.runtime.panicTypeError())
|
||||
return val
|
||||
}
|
||||
return val
|
||||
panic(call.runtime.panicTypeError("Object.Seal is nil"))
|
||||
}
|
||||
|
||||
func builtinObjectIsFrozen(call FunctionCall) Value {
|
||||
@@ -236,7 +234,7 @@ func builtinObjectIsFrozen(call FunctionCall) Value {
|
||||
})
|
||||
return boolValue(result)
|
||||
}
|
||||
panic(call.runtime.panicTypeError())
|
||||
panic(call.runtime.panicTypeError("Object.IsFrozen is nil"))
|
||||
}
|
||||
|
||||
func builtinObjectFreeze(call FunctionCall) Value {
|
||||
@@ -259,10 +257,9 @@ func builtinObjectFreeze(call FunctionCall) Value {
|
||||
return true
|
||||
})
|
||||
obj.extensible = false
|
||||
} else {
|
||||
panic(call.runtime.panicTypeError())
|
||||
return val
|
||||
}
|
||||
return val
|
||||
panic(call.runtime.panicTypeError("Object.Freeze is nil"))
|
||||
}
|
||||
|
||||
func builtinObjectKeys(call FunctionCall) Value {
|
||||
@@ -273,7 +270,7 @@ func builtinObjectKeys(call FunctionCall) Value {
|
||||
})
|
||||
return objectValue(call.runtime.newArrayOf(keys))
|
||||
}
|
||||
panic(call.runtime.panicTypeError())
|
||||
panic(call.runtime.panicTypeError("Object.Keys is nil"))
|
||||
}
|
||||
|
||||
func builtinObjectGetOwnPropertyNames(call FunctionCall) Value {
|
||||
|
||||
@@ -169,7 +169,7 @@ func (rt *runtime) cmplEvaluateNodeBracketExpression(node *nodeBracketExpression
|
||||
// TODO Pass in base value as-is, and defer toObject till later?
|
||||
obj, err := rt.objectCoerce(targetValue)
|
||||
if err != nil {
|
||||
panic(rt.panicTypeError("Cannot access member '%s' of %s", memberValue.string(), err.Error(), at(node.idx)))
|
||||
panic(rt.panicTypeError("Cannot access member %q of %s", memberValue.string(), err, at(node.idx)))
|
||||
}
|
||||
return toValue(newPropertyReference(rt, obj, memberValue.string(), false, at(node.idx)))
|
||||
}
|
||||
@@ -201,7 +201,7 @@ func (rt *runtime) cmplEvaluateNodeCallExpression(node *nodeCallExpression, with
|
||||
eval = rf.name == "eval" // Possible direct eval
|
||||
default:
|
||||
// FIXME?
|
||||
panic(rt.panicTypeError("Here be dragons"))
|
||||
panic(rt.panicTypeError("unexpected callee type %T to node call expression", rf))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -226,7 +226,7 @@ func (rt *runtime) cmplEvaluateNodeCallExpression(node *nodeCallExpression, with
|
||||
// FIXME Maybe typeof?
|
||||
panic(rt.panicTypeError("%v is not a function", vl, atv))
|
||||
}
|
||||
panic(rt.panicTypeError("'%s' is not a function", name, atv))
|
||||
panic(rt.panicTypeError("%q is not a function", name, atv))
|
||||
}
|
||||
|
||||
rt.scope.frame.offset = int(atv)
|
||||
@@ -249,7 +249,7 @@ func (rt *runtime) cmplEvaluateNodeDotExpression(node *nodeDotExpression) Value
|
||||
// TODO Pass in base value as-is, and defer toObject till later?
|
||||
obj, err := rt.objectCoerce(targetValue)
|
||||
if err != nil {
|
||||
panic(rt.panicTypeError("Cannot access member '%s' of %s", node.identifier, err.Error(), at(node.idx)))
|
||||
panic(rt.panicTypeError("Cannot access member %q of %s", node.identifier, err, at(node.idx)))
|
||||
}
|
||||
return toValue(newPropertyReference(rt, obj, node.identifier, false, at(node.idx)))
|
||||
}
|
||||
@@ -270,7 +270,7 @@ func (rt *runtime) cmplEvaluateNodeNewExpression(node *nodeNewExpression) Value
|
||||
case *stashReference:
|
||||
name = rf.name
|
||||
default:
|
||||
panic(rt.panicTypeError("Here be dragons"))
|
||||
panic(rt.panicTypeError("node new expression unexpected callee type %T", rf))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -80,7 +80,7 @@ func TestErrorContext(t *testing.T) {
|
||||
`)
|
||||
{
|
||||
err := asError(t, err)
|
||||
is(err.message, "'undefined' is not a function")
|
||||
is(err.message, `"undefined" is not a function`)
|
||||
is(len(err.trace), 1)
|
||||
is(err.trace[0].location(), "<anonymous>:2:13")
|
||||
}
|
||||
@@ -90,7 +90,7 @@ func TestErrorContext(t *testing.T) {
|
||||
`)
|
||||
{
|
||||
err := asError(t, err)
|
||||
is(err.message, "'abc' is not a function")
|
||||
is(err.message, `"abc" is not a function`)
|
||||
is(len(err.trace), 1)
|
||||
is(err.trace[0].location(), "<anonymous>:2:14")
|
||||
}
|
||||
@@ -100,7 +100,7 @@ func TestErrorContext(t *testing.T) {
|
||||
`)
|
||||
{
|
||||
err := asError(t, err)
|
||||
is(err.message, "'abc' is not a function")
|
||||
is(err.message, `"abc" is not a function`)
|
||||
is(len(err.trace), 1)
|
||||
is(err.trace[0].location(), "<anonymous>:2:14")
|
||||
}
|
||||
@@ -111,7 +111,7 @@ func TestErrorContext(t *testing.T) {
|
||||
`)
|
||||
{
|
||||
err := asError(t, err)
|
||||
is(err.message, "'ghi' is not a function")
|
||||
is(err.message, `"ghi" is not a function`)
|
||||
is(len(err.trace), 1)
|
||||
is(err.trace[0].location(), "<anonymous>:3:13")
|
||||
}
|
||||
@@ -127,7 +127,7 @@ func TestErrorContext(t *testing.T) {
|
||||
`)
|
||||
{
|
||||
err := asError(t, err)
|
||||
is(err.message, "'undefined' is not a function")
|
||||
is(err.message, `"undefined" is not a function`)
|
||||
is(len(err.trace), 3)
|
||||
is(err.trace[0].location(), "def (<anonymous>:3:17)")
|
||||
is(err.trace[1].location(), "abc (<anonymous>:6:17)")
|
||||
@@ -174,7 +174,7 @@ func TestErrorContext(t *testing.T) {
|
||||
`)
|
||||
{
|
||||
err := asError(t, err)
|
||||
is(err.message, "'xyzzy' is not a function")
|
||||
is(err.message, `"xyzzy" is not a function`)
|
||||
is(len(err.trace), 1)
|
||||
is(err.trace[0].location(), "<anonymous>:1:1")
|
||||
}
|
||||
@@ -251,7 +251,7 @@ func TestErrorContext(t *testing.T) {
|
||||
f, _ := vm.Get("C")
|
||||
_, err := f.Call(UndefinedValue())
|
||||
err1 := asError(t, err)
|
||||
is(err1.message, "Cannot access member 'prop' of null")
|
||||
is(err1.message, `Cannot access member "prop" of null`)
|
||||
is(len(err1.trace), 1)
|
||||
is(err1.trace[0].location(), "C (file1.js:7:5)")
|
||||
}
|
||||
|
||||
@@ -119,14 +119,14 @@ func (rt *runtime) calculateBinaryExpression(operator token.Token, left Value, r
|
||||
case token.INSTANCEOF:
|
||||
rightValue := right.resolve()
|
||||
if !rightValue.IsObject() {
|
||||
panic(rt.panicTypeError("Expecting a function in instanceof check, but got: %v", rightValue))
|
||||
panic(rt.panicTypeError("invalid kind %s for instanceof (expected object)", rightValue.kind))
|
||||
}
|
||||
return boolValue(rightValue.object().hasInstance(leftValue))
|
||||
|
||||
case token.IN:
|
||||
rightValue := right.resolve()
|
||||
if !rightValue.IsObject() {
|
||||
panic(rt.panicTypeError())
|
||||
panic(rt.panicTypeError("invalid kind %s for in (expected object)", rightValue.kind))
|
||||
}
|
||||
return boolValue(rightValue.object().hasProperty(leftValue.string()))
|
||||
}
|
||||
|
||||
@@ -229,7 +229,7 @@ func TestFunction_bind(t *testing.T) {
|
||||
|
||||
test(`raise:
|
||||
Math.bind();
|
||||
`, "TypeError: 'bind' is not a function")
|
||||
`, `TypeError: "bind" is not a function`)
|
||||
|
||||
test(`
|
||||
function construct(fn, arguments) {
|
||||
@@ -268,7 +268,7 @@ func TestFunction_toString(t *testing.T) {
|
||||
|
||||
test(`raise:
|
||||
Function.prototype.toString.call(undefined);
|
||||
`, "TypeError")
|
||||
`, "TypeError: Function.Class environment != Function")
|
||||
|
||||
test(`
|
||||
abc = function() { return -1 ;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
package otto
|
||||
|
||||
//go:generate go run ./tools/gen-jscore -output inline.go
|
||||
//go:generate stringer -type=valueKind -trimprefix=value -output=value_kind.gen.go
|
||||
|
||||
@@ -210,7 +210,7 @@ func objectCanPutDetails(obj *object, name string) (canPut bool, prop *property,
|
||||
canPut = setter != nil
|
||||
return
|
||||
default:
|
||||
panic(obj.runtime.panicTypeError())
|
||||
panic(obj.runtime.panicTypeError("unexpected type %T to Object.CanPutDetails", prop.value))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -234,7 +234,7 @@ func objectCanPutDetails(obj *object, name string) (canPut bool, prop *property,
|
||||
canPut = setter != nil
|
||||
return
|
||||
default:
|
||||
panic(obj.runtime.panicTypeError())
|
||||
panic(obj.runtime.panicTypeError("unexpected type %T to Object.CanPutDetails", prop.value))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -282,22 +282,23 @@ func objectPut(obj *object, name string, value Value, throw bool) {
|
||||
}
|
||||
}
|
||||
obj.defineProperty(name, value, 0o111, throw)
|
||||
} else {
|
||||
switch propertyValue := prop.value.(type) {
|
||||
case Value:
|
||||
prop.value = value
|
||||
obj.defineOwnProperty(name, *prop, throw)
|
||||
case propertyGetSet:
|
||||
if propertyValue[1] != nil {
|
||||
propertyValue[1].call(toValue(obj), []Value{value}, false, nativeFrame)
|
||||
return
|
||||
}
|
||||
if throw {
|
||||
panic(obj.runtime.panicTypeError())
|
||||
}
|
||||
default:
|
||||
panic(obj.runtime.panicTypeError())
|
||||
return
|
||||
}
|
||||
|
||||
switch propertyValue := prop.value.(type) {
|
||||
case Value:
|
||||
prop.value = value
|
||||
obj.defineOwnProperty(name, *prop, throw)
|
||||
case propertyGetSet:
|
||||
if propertyValue[1] != nil {
|
||||
propertyValue[1].call(toValue(obj), []Value{value}, false, nativeFrame)
|
||||
return
|
||||
}
|
||||
if throw {
|
||||
panic(obj.runtime.panicTypeError("Object.Put nil second parameter to propertyGetSet"))
|
||||
}
|
||||
default:
|
||||
panic(obj.runtime.panicTypeError("Object.Put unexpected type %T", prop.value))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -312,9 +313,9 @@ func objectHasOwnProperty(obj *object, name string) bool {
|
||||
|
||||
// 8.12.9.
|
||||
func objectDefineOwnProperty(obj *object, name string, descriptor property, throw bool) bool {
|
||||
reject := func() bool {
|
||||
reject := func(reason string) bool {
|
||||
if throw {
|
||||
panic(obj.runtime.panicTypeError())
|
||||
panic(obj.runtime.panicTypeError("Object.DefineOwnProperty: %s", reason))
|
||||
}
|
||||
return false
|
||||
}
|
||||
@@ -322,7 +323,7 @@ func objectDefineOwnProperty(obj *object, name string, descriptor property, thro
|
||||
prop, exists := obj.readProperty(name)
|
||||
if !exists {
|
||||
if !obj.extensible {
|
||||
return reject()
|
||||
return reject("not exists and not extensible")
|
||||
}
|
||||
if newGetSet, isAccessor := descriptor.value.(propertyGetSet); isAccessor {
|
||||
if newGetSet[0] == &nilGetSetObject {
|
||||
@@ -347,12 +348,12 @@ func objectDefineOwnProperty(obj *object, name string, descriptor property, thro
|
||||
configurable := prop.configurable()
|
||||
if !configurable {
|
||||
if descriptor.configurable() {
|
||||
return reject()
|
||||
return reject("property and descriptor not configurable")
|
||||
}
|
||||
// Test that, if enumerable is set on the property descriptor, then it should
|
||||
// be the same as the existing property
|
||||
if descriptor.enumerateSet() && descriptor.enumerable() != prop.enumerable() {
|
||||
return reject()
|
||||
return reject("property not configurable and enumerable miss match")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -364,17 +365,17 @@ func objectDefineOwnProperty(obj *object, name string, descriptor property, thro
|
||||
case isDataDescriptor != descriptor.isDataDescriptor():
|
||||
// DataDescriptor <=> AccessorDescriptor
|
||||
if !configurable {
|
||||
return reject()
|
||||
return reject("property descriptor not configurable")
|
||||
}
|
||||
case isDataDescriptor && descriptor.isDataDescriptor():
|
||||
// DataDescriptor <=> DataDescriptor
|
||||
if !configurable {
|
||||
if !prop.writable() && descriptor.writable() {
|
||||
return reject()
|
||||
return reject("property not configurable or writeable and descriptor not writeable")
|
||||
}
|
||||
if !prop.writable() {
|
||||
if descriptor.value != nil && !sameValue(value, descriptor.value.(Value)) {
|
||||
return reject()
|
||||
return reject("property not configurable or writeable and descriptor not the same")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -400,7 +401,7 @@ func objectDefineOwnProperty(obj *object, name string, descriptor property, thro
|
||||
}
|
||||
if !configurable {
|
||||
if (presentGet && (getSet[0] != newGetSet[0])) || (presentSet && (getSet[1] != newGetSet[1])) {
|
||||
return reject()
|
||||
return reject("access descriptor not configurable")
|
||||
}
|
||||
}
|
||||
descriptor.value = newGetSet
|
||||
|
||||
@@ -63,7 +63,7 @@ func TestObject_create(t *testing.T) {
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test(`raise: Object.create()`, "TypeError")
|
||||
test(`raise: Object.create()`, "TypeError: Object.Create is nil")
|
||||
|
||||
test(`
|
||||
var abc = Object.create(null)
|
||||
@@ -121,7 +121,7 @@ func TestObject_isExtensible(t *testing.T) {
|
||||
|
||||
test(`raise:
|
||||
Object.isExtensible();
|
||||
`, "TypeError")
|
||||
`, "TypeError: Object.IsExtensible is nil")
|
||||
|
||||
// FIXME terst, Why raise?
|
||||
test(`raise:
|
||||
@@ -139,7 +139,7 @@ func TestObject_preventExtensions(t *testing.T) {
|
||||
|
||||
test(`raise:
|
||||
Object.preventExtensions()
|
||||
`, "TypeError")
|
||||
`, "TypeError: Object.PreventExtensions is nil")
|
||||
|
||||
test(`raise:
|
||||
var abc = { def: true };
|
||||
@@ -178,7 +178,7 @@ func TestObject_seal(t *testing.T) {
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test(`raise: Object.seal()`, "TypeError")
|
||||
test(`raise: Object.seal()`, "TypeError: Object.Seal is nil")
|
||||
|
||||
test(`
|
||||
var abc = {a:1,b:1,c:3};
|
||||
@@ -211,7 +211,7 @@ func TestObject_isFrozen(t *testing.T) {
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test(`raise: Object.isFrozen()`, "TypeError")
|
||||
test(`raise: Object.isFrozen()`, "TypeError: Object.IsFrozen is nil")
|
||||
test(`Object.isFrozen(Object.preventExtensions({a:1}))`, false)
|
||||
test(`Object.isFrozen({})`, false)
|
||||
|
||||
@@ -235,7 +235,7 @@ func TestObject_freeze(t *testing.T) {
|
||||
tt(t, func() {
|
||||
test, _ := test()
|
||||
|
||||
test(`raise: Object.freeze()`, "TypeError")
|
||||
test(`raise: Object.freeze()`, "TypeError: Object.Freeze is nil")
|
||||
|
||||
test(`
|
||||
var abc = {a:1,b:2,c:3};
|
||||
@@ -395,7 +395,7 @@ func TestObjectGetterSetter(t *testing.T) {
|
||||
writable: true
|
||||
}
|
||||
}).abc;
|
||||
`, "TypeError")
|
||||
`, "TypeError: toPropertyDescriptor descriptor writeSet")
|
||||
|
||||
test(`raise:
|
||||
Object.create({}, {
|
||||
@@ -406,7 +406,7 @@ func TestObjectGetterSetter(t *testing.T) {
|
||||
writable: false
|
||||
}
|
||||
}).abc;
|
||||
`, "TypeError")
|
||||
`, "TypeError: toPropertyDescriptor descriptor writeSet")
|
||||
|
||||
test(`
|
||||
Object.create({}, {
|
||||
@@ -512,7 +512,7 @@ func TestObjectGetterSetter(t *testing.T) {
|
||||
return 2;
|
||||
}
|
||||
});
|
||||
`, "TypeError")
|
||||
`, `TypeError: Array.DefineOwnProperty ["function () {\n return 2;\n }" <nil>] is not a value`)
|
||||
|
||||
test(`
|
||||
var abc = {};
|
||||
|
||||
@@ -21,7 +21,7 @@ func Test_panic(t *testing.T) {
|
||||
var abc = [];
|
||||
Object.defineProperty(abc, "0", { writable: false });
|
||||
Object.defineProperty(abc, "0", { value: false, writable: false });
|
||||
`, "TypeError")
|
||||
`, "TypeError: Array.DefineOwnProperty Object.DefineOwnProperty failed")
|
||||
|
||||
// Test that a regular expression can contain \c0410 (CYRILLIC CAPITAL LETTER A)
|
||||
// without panicking
|
||||
|
||||
10
property.go
10
property.go
@@ -117,7 +117,7 @@ func (p property) isEmpty() bool {
|
||||
func toPropertyDescriptor(rt *runtime, value Value) property {
|
||||
objectDescriptor := value.object()
|
||||
if objectDescriptor == nil {
|
||||
panic(rt.panicTypeError())
|
||||
panic(rt.panicTypeError("toPropertyDescriptor on nil"))
|
||||
}
|
||||
|
||||
var descriptor property
|
||||
@@ -153,7 +153,7 @@ func toPropertyDescriptor(rt *runtime, value Value) property {
|
||||
value := objectDescriptor.get("get")
|
||||
if value.IsDefined() {
|
||||
if !value.isCallable() {
|
||||
panic(rt.panicTypeError())
|
||||
panic(rt.panicTypeError("toPropertyDescriptor get not callable"))
|
||||
}
|
||||
getter = value.object()
|
||||
getterSetter = true
|
||||
@@ -167,7 +167,7 @@ func toPropertyDescriptor(rt *runtime, value Value) property {
|
||||
value := objectDescriptor.get("set")
|
||||
if value.IsDefined() {
|
||||
if !value.isCallable() {
|
||||
panic(rt.panicTypeError())
|
||||
panic(rt.panicTypeError("toPropertyDescriptor set not callable"))
|
||||
}
|
||||
setter = value.object()
|
||||
getterSetter = true
|
||||
@@ -179,14 +179,14 @@ func toPropertyDescriptor(rt *runtime, value Value) property {
|
||||
|
||||
if getterSetter {
|
||||
if descriptor.writeSet() {
|
||||
panic(rt.panicTypeError())
|
||||
panic(rt.panicTypeError("toPropertyDescriptor descriptor writeSet"))
|
||||
}
|
||||
descriptor.value = propertyGetSet{getter, setter}
|
||||
}
|
||||
|
||||
if objectDescriptor.hasProperty("value") {
|
||||
if getterSetter {
|
||||
panic(rt.panicTypeError())
|
||||
panic(rt.panicTypeError("toPropertyDescriptor value getterSetter"))
|
||||
}
|
||||
descriptor.value = objectDescriptor.get("value")
|
||||
}
|
||||
|
||||
15
runtime.go
15
runtime.go
@@ -147,7 +147,7 @@ func (rt *runtime) tryCatchEvaluate(inner func() Value) (tryValue Value, isExcep
|
||||
func (rt *runtime) toObject(value Value) *object {
|
||||
switch value.kind {
|
||||
case valueEmpty, valueUndefined, valueNull:
|
||||
panic(rt.panicTypeError())
|
||||
panic(rt.panicTypeError("toObject unsupported kind %s", value.kind))
|
||||
case valueBoolean:
|
||||
return rt.newBoolean(value)
|
||||
case valueString:
|
||||
@@ -157,7 +157,7 @@ func (rt *runtime) toObject(value Value) *object {
|
||||
case valueObject:
|
||||
return value.object()
|
||||
default:
|
||||
panic(rt.panicTypeError())
|
||||
panic(rt.panicTypeError("toObject unknown kind %s", value.kind))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -176,19 +176,18 @@ func (rt *runtime) objectCoerce(value Value) (*object, error) {
|
||||
case valueObject:
|
||||
return value.object(), nil
|
||||
default:
|
||||
panic(rt.panicTypeError())
|
||||
panic(rt.panicTypeError("objectCoerce unknown kind %s", value.kind))
|
||||
}
|
||||
}
|
||||
|
||||
func checkObjectCoercible(rt *runtime, value Value) {
|
||||
isObject, mustCoerce := testObjectCoercible(value)
|
||||
if !isObject && !mustCoerce {
|
||||
panic(rt.panicTypeError())
|
||||
panic(rt.panicTypeError("checkObjectCoercible not object or mustCoerce"))
|
||||
}
|
||||
}
|
||||
|
||||
// testObjectCoercible
|
||||
|
||||
// testObjectCoercible.
|
||||
func testObjectCoercible(value Value) (isObject, mustCoerce bool) { //nolint: nonamedreturns
|
||||
switch value.kind {
|
||||
case valueReference, valueEmpty, valueNull, valueUndefined:
|
||||
@@ -198,7 +197,7 @@ func testObjectCoercible(value Value) (isObject, mustCoerce bool) { //nolint: no
|
||||
case valueObject:
|
||||
return true, false
|
||||
default:
|
||||
panic("this should never happen")
|
||||
panic(fmt.Sprintf("testObjectCoercible unknown kind %s", value.kind))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -534,7 +533,7 @@ func (rt *runtime) convertCallParameter(v Value, t reflect.Type) (reflect.Value,
|
||||
|
||||
r, err := rt.convertCallParameter(rv, t.Out(0))
|
||||
if err != nil {
|
||||
panic(rt.panicTypeError(err.Error()))
|
||||
panic(rt.panicTypeError("convertCallParameter Func: %s", err))
|
||||
}
|
||||
|
||||
return []reflect.Value{r}
|
||||
|
||||
@@ -627,11 +627,11 @@ func Test_instanceof(t *testing.T) {
|
||||
|
||||
test(`raise:
|
||||
abc = {} instanceof "abc";
|
||||
`, "TypeError: Expecting a function in instanceof check, but got: abc")
|
||||
`, "TypeError: invalid kind String for instanceof (expected object)")
|
||||
|
||||
test(`raise:
|
||||
"xyzzy" instanceof Math;
|
||||
`, "TypeError")
|
||||
`, "TypeError: Object.hasInstance not callable")
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
2
stash.go
2
stash.go
@@ -194,7 +194,7 @@ func (s *dclStash) getBinding(name string, throw bool) Value {
|
||||
}
|
||||
if !prop.mutable && !prop.readable {
|
||||
if throw { // strict?
|
||||
panic(s.rt.panicTypeError())
|
||||
panic(s.rt.panicTypeError("getBinding property %s not mutable and not readable", name))
|
||||
}
|
||||
return Value{}
|
||||
}
|
||||
|
||||
@@ -55,6 +55,13 @@ func arrayDefineOwnProperty(obj *object, name string, descriptor property, throw
|
||||
if !valid {
|
||||
panic("Array.length != Value{}")
|
||||
}
|
||||
|
||||
reject := func(reason string) bool {
|
||||
if throw {
|
||||
panic(obj.runtime.panicTypeError("Array.DefineOwnProperty %s", reason))
|
||||
}
|
||||
return false
|
||||
}
|
||||
length := lengthValue.value.(uint32)
|
||||
if name == propertyLength {
|
||||
if descriptor.value == nil {
|
||||
@@ -62,7 +69,7 @@ func arrayDefineOwnProperty(obj *object, name string, descriptor property, throw
|
||||
}
|
||||
newLengthValue, isValue := descriptor.value.(Value)
|
||||
if !isValue {
|
||||
panic(obj.runtime.panicTypeError())
|
||||
panic(obj.runtime.panicTypeError("Array.DefineOwnProperty %q is not a value", descriptor.value))
|
||||
}
|
||||
newLength := arrayUint32(obj.runtime, newLengthValue)
|
||||
descriptor.value = uint32Value(newLength)
|
||||
@@ -70,7 +77,7 @@ func arrayDefineOwnProperty(obj *object, name string, descriptor property, throw
|
||||
return objectDefineOwnProperty(obj, name, descriptor, throw)
|
||||
}
|
||||
if !lengthProperty.writable() {
|
||||
goto Reject
|
||||
return reject("property length for not writable")
|
||||
}
|
||||
newWritable := true
|
||||
if descriptor.mode&0o700 == 0 {
|
||||
@@ -89,7 +96,7 @@ func arrayDefineOwnProperty(obj *object, name string, descriptor property, throw
|
||||
descriptor.mode &= 0o077
|
||||
}
|
||||
objectDefineOwnProperty(obj, name, descriptor, false)
|
||||
goto Reject
|
||||
return reject("delete failed")
|
||||
}
|
||||
}
|
||||
if !newWritable {
|
||||
@@ -98,10 +105,10 @@ func arrayDefineOwnProperty(obj *object, name string, descriptor property, throw
|
||||
}
|
||||
} else if index := stringToArrayIndex(name); index >= 0 {
|
||||
if index >= int64(length) && !lengthProperty.writable() {
|
||||
goto Reject
|
||||
return reject("property length not writable")
|
||||
}
|
||||
if !objectDefineOwnProperty(obj, strconv.FormatInt(index, 10), descriptor, false) {
|
||||
goto Reject
|
||||
return reject("Object.DefineOwnProperty failed")
|
||||
}
|
||||
if index >= int64(length) {
|
||||
lengthProperty.value = uint32Value(uint32(index + 1))
|
||||
@@ -110,9 +117,4 @@ func arrayDefineOwnProperty(obj *object, name string, descriptor property, throw
|
||||
}
|
||||
}
|
||||
return objectDefineOwnProperty(obj, name, descriptor, throw)
|
||||
Reject:
|
||||
if throw {
|
||||
panic(obj.runtime.panicTypeError())
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -140,8 +140,11 @@ func (o *object) dateValue() dateObject {
|
||||
}
|
||||
|
||||
func dateObjectOf(rt *runtime, date *object) dateObject {
|
||||
if date == nil || date.class != classDateName {
|
||||
panic(rt.panicTypeError())
|
||||
if date == nil {
|
||||
panic(rt.panicTypeError("Date.ObjectOf is nil"))
|
||||
}
|
||||
if date.class != classDateName {
|
||||
panic(rt.panicTypeError("Date.ObjectOf %q != %q", date.class, classDateName))
|
||||
}
|
||||
return date.dateValue()
|
||||
}
|
||||
|
||||
@@ -107,8 +107,9 @@ func (fn bindFunctionObject) construct(argumentList []Value) Value {
|
||||
case nodeFunctionObject:
|
||||
argumentList = append(fn.argumentList, argumentList...)
|
||||
return obj.construct(argumentList)
|
||||
default:
|
||||
panic(fn.target.runtime.panicTypeError("construct unknown type %T", obj.value))
|
||||
}
|
||||
panic(fn.target.runtime.panicTypeError())
|
||||
}
|
||||
|
||||
// nodeFunctionObject.
|
||||
@@ -246,14 +247,14 @@ func (o *object) construct(argumentList []Value) Value {
|
||||
func (o *object) hasInstance(of Value) bool {
|
||||
if !o.isCall() {
|
||||
// We should not have a hasInstance method
|
||||
panic(o.runtime.panicTypeError())
|
||||
panic(o.runtime.panicTypeError("Object.hasInstance not callable"))
|
||||
}
|
||||
if !of.IsObject() {
|
||||
return false
|
||||
}
|
||||
prototype := o.get("prototype")
|
||||
if !prototype.IsObject() {
|
||||
panic(o.runtime.panicTypeError())
|
||||
panic(o.runtime.panicTypeError("Object.hasInstance prototype %q is not an object", prototype))
|
||||
}
|
||||
prototypeObject := prototype.object()
|
||||
|
||||
@@ -306,7 +307,7 @@ func (f *FunctionCall) thisObject() *object {
|
||||
|
||||
func (f *FunctionCall) thisClassObject(class string) *object {
|
||||
if o := f.thisObject(); o.class != class {
|
||||
panic(f.runtime.panicTypeError())
|
||||
panic(f.runtime.panicTypeError("Function.Class %s != %s", o.class, class))
|
||||
}
|
||||
return f.thisObj
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@ func (o goStructObject) setValue(rt *runtime, name string, value Value) bool {
|
||||
fieldValue := o.getValue(name)
|
||||
converted, err := rt.convertCallParameter(value, fieldValue.Type())
|
||||
if err != nil {
|
||||
panic(rt.panicTypeError(err.Error()))
|
||||
panic(rt.panicTypeError("Object.setValue convertCallParameter: %s", err))
|
||||
}
|
||||
fieldValue.Set(converted)
|
||||
|
||||
|
||||
10
value.go
10
value.go
@@ -118,10 +118,7 @@ func (v Value) call(rt *runtime, this Value, argumentList ...interface{}) Value
|
||||
if function, ok := v.value.(*object); ok {
|
||||
return function.call(this, function.runtime.toValueArray(argumentList...), false, nativeFrame)
|
||||
}
|
||||
if rt == nil {
|
||||
panic("FIXME TypeError")
|
||||
}
|
||||
panic(rt.panicTypeError())
|
||||
panic(rt.panicTypeError("call %q is not an object", v.value))
|
||||
}
|
||||
|
||||
func (v Value) constructSafe(rt *runtime, this Value, argumentList ...interface{}) (Value, error) {
|
||||
@@ -136,10 +133,7 @@ func (v Value) construct(rt *runtime, this Value, argumentList ...interface{}) V
|
||||
if fn, ok := v.value.(*object); ok {
|
||||
return fn.construct(fn.runtime.toValueArray(argumentList...))
|
||||
}
|
||||
if rt == nil {
|
||||
panic("FIXME TypeError")
|
||||
}
|
||||
panic(rt.panicTypeError())
|
||||
panic(rt.panicTypeError("construct %q is not an object", v.value))
|
||||
}
|
||||
|
||||
// IsPrimitive will return true if value is a primitive (any kind of primitive).
|
||||
|
||||
31
value_kind.gen.go
Normal file
31
value_kind.gen.go
Normal file
@@ -0,0 +1,31 @@
|
||||
// Code generated by "stringer -type=valueKind -trimprefix=value -output=value_kind.gen.go"; DO NOT EDIT.
|
||||
|
||||
package otto
|
||||
|
||||
import "strconv"
|
||||
|
||||
func _() {
|
||||
// An "invalid array index" compiler error signifies that the constant values have changed.
|
||||
// Re-run the stringer command to generate them again.
|
||||
var x [1]struct{}
|
||||
_ = x[valueUndefined-0]
|
||||
_ = x[valueNull-1]
|
||||
_ = x[valueNumber-2]
|
||||
_ = x[valueString-3]
|
||||
_ = x[valueBoolean-4]
|
||||
_ = x[valueObject-5]
|
||||
_ = x[valueEmpty-6]
|
||||
_ = x[valueResult-7]
|
||||
_ = x[valueReference-8]
|
||||
}
|
||||
|
||||
const _valueKind_name = "UndefinedNullNumberStringBooleanObjectEmptyResultReference"
|
||||
|
||||
var _valueKind_index = [...]uint8{0, 9, 13, 19, 25, 32, 38, 43, 49, 58}
|
||||
|
||||
func (i valueKind) String() string {
|
||||
if i < 0 || i >= valueKind(len(_valueKind_index)-1) {
|
||||
return "valueKind(" + strconv.FormatInt(int64(i), 10) + ")"
|
||||
}
|
||||
return _valueKind_name[_valueKind_index[i]:_valueKind_index[i+1]]
|
||||
}
|
||||
Reference in New Issue
Block a user