aboutsummaryrefslogblamecommitdiffstats
path: root/vendor/github.com/robertkrimen/otto/builtin_object.go
blob: c2433f7be2b3d9b7cea9b8b60bd69e6b6e8f7bee (plain) (tree)
1
2
3
4
5
6
7
8
9
10









                                             
                           






                                                               
                                                                  
                                                   
                           














                                                                   
                                                 






                                                                    
                                 




                                                   
                                        


                                               
                         


                                                                  
                                                 


                                                           
                                
         
                         
















                                                                            
                                                    
         
                                                     





                                                            
                                                    


                                    
                                








                                                                      
                                                    

         
                                         

                                                 
                              







                                                                               
                                                    
         

                                                                          







                                                              
                                                    



                                                             
                                                                                      









                                                                   
                                                    








                                                                    
                                                                                              












                                                                        
                                            






                                                               
                                                    



















                                                               
                                            













                                                                                                                
                                                    



















                                                                           
                                            






















                                                                                                    
                                                    











                                                                                    
                                            











                                                                                             
                                            
 
package otto

import (
    "fmt"
)

// Object

func builtinObject(call FunctionCall) Value {
    value := call.Argument(0)
    switch value.kind {
    case valueUndefined, valueNull:
        return toValue_object(call.runtime.newObject())
    }

    return toValue_object(call.runtime.toObject(value))
}

func builtinNewObject(self *_object, argumentList []Value) Value {
    value := valueOfArrayIndex(argumentList, 0)
    switch value.kind {
    case valueNull, valueUndefined:
    case valueNumber, valueString, valueBoolean:
        return toValue_object(self.runtime.toObject(value))
    case valueObject:
        return value
    default:
    }
    return toValue_object(self.runtime.newObject())
}

func builtinObject_valueOf(call FunctionCall) Value {
    return toValue_object(call.thisObject())
}

func builtinObject_hasOwnProperty(call FunctionCall) Value {
    propertyName := call.Argument(0).string()
    thisObject := call.thisObject()
    return toValue_bool(thisObject.hasOwnProperty(propertyName))
}

func builtinObject_isPrototypeOf(call FunctionCall) Value {
    value := call.Argument(0)
    if !value.IsObject() {
        return falseValue
    }
    prototype := call.toObject(value).prototype
    thisObject := call.thisObject()
    for prototype != nil {
        if thisObject == prototype {
            return trueValue
        }
        prototype = prototype.prototype
    }
    return falseValue
}

func builtinObject_propertyIsEnumerable(call FunctionCall) Value {
    propertyName := call.Argument(0).string()
    thisObject := call.thisObject()
    property := thisObject.getOwnProperty(propertyName)
    if property != nil && property.enumerable() {
        return trueValue
    }
    return falseValue
}

func builtinObject_toString(call FunctionCall) Value {
    result := ""
    if call.This.IsUndefined() {
        result = "[object Undefined]"
    } else if call.This.IsNull() {
        result = "[object Null]"
    } else {
        result = fmt.Sprintf("[object %s]", call.thisObject().class)
    }
    return toValue_string(result)
}

func builtinObject_toLocaleString(call FunctionCall) Value {
    toString := call.thisObject().get("toString")
    if !toString.isCallable() {
        panic(call.runtime.panicTypeError())
    }
    return toString.call(call.runtime, call.This)
}

func builtinObject_getPrototypeOf(call FunctionCall) Value {
    objectValue := call.Argument(0)
    object := objectValue._object()
    if object == nil {
        panic(call.runtime.panicTypeError())
    }

    if object.prototype == nil {
        return nullValue
    }

    return toValue_object(object.prototype)
}

func builtinObject_getOwnPropertyDescriptor(call FunctionCall) Value {
    objectValue := call.Argument(0)
    object := objectValue._object()
    if object == nil {
        panic(call.runtime.panicTypeError())
    }

    name := call.Argument(1).string()
    descriptor := object.getOwnProperty(name)
    if descriptor == nil {
        return Value{}
    }
    return toValue_object(call.runtime.fromPropertyDescriptor(*descriptor))
}

func builtinObject_defineProperty(call FunctionCall) Value {
    objectValue := call.Argument(0)
    object := objectValue._object()
    if object == nil {
        panic(call.runtime.panicTypeError())
    }
    name := call.Argument(1).string()
    descriptor := toPropertyDescriptor(call.runtime, call.Argument(2))
    object.defineOwnProperty(name, descriptor, true)
    return objectValue
}

func builtinObject_defineProperties(call FunctionCall) Value {
    objectValue := call.Argument(0)
    object := objectValue._object()
    if object == nil {
        panic(call.runtime.panicTypeError())
    }

    properties := call.runtime.toObject(call.Argument(1))
    properties.enumerate(false, func(name string) bool {
        descriptor := toPropertyDescriptor(call.runtime, properties.get(name))
        object.defineOwnProperty(name, descriptor, true)
        return true
    })

    return objectValue
}

func builtinObject_create(call FunctionCall) Value {
    prototypeValue := call.Argument(0)
    if !prototypeValue.IsNull() && !prototypeValue.IsObject() {
        panic(call.runtime.panicTypeError())
    }

    object := call.runtime.newObject()
    object.prototype = prototypeValue._object()

    propertiesValue := call.Argument(1)
    if propertiesValue.IsDefined() {
        properties := call.runtime.toObject(propertiesValue)
        properties.enumerate(false, func(name string) bool {
            descriptor := toPropertyDescriptor(call.runtime, properties.get(name))
            object.defineOwnProperty(name, descriptor, true)
            return true
        })
    }

    return toValue_object(object)
}

func builtinObject_isExtensible(call FunctionCall) Value {
    object := call.Argument(0)
    if object := object._object(); object != nil {
        return toValue_bool(object.extensible)
    }
    panic(call.runtime.panicTypeError())
}

func builtinObject_preventExtensions(call FunctionCall) Value {
    object := call.Argument(0)
    if object := object._object(); object != nil {
        object.extensible = false
    } else {
        panic(call.runtime.panicTypeError())
    }
    return object
}

func builtinObject_isSealed(call FunctionCall) Value {
    object := call.Argument(0)
    if object := object._object(); object != nil {
        if object.extensible {
            return toValue_bool(false)
        }
        result := true
        object.enumerate(true, func(name string) bool {
            property := object.getProperty(name)
            if property.configurable() {
                result = false
            }
            return true
        })
        return toValue_bool(result)
    }
    panic(call.runtime.panicTypeError())
}

func builtinObject_seal(call FunctionCall) Value {
    object := call.Argument(0)
    if object := object._object(); object != nil {
        object.enumerate(true, func(name string) bool {
            if property := object.getOwnProperty(name); nil != property && property.configurable() {
                property.configureOff()
                object.defineOwnProperty(name, *property, true)
            }
            return true
        })
        object.extensible = false
    } else {
        panic(call.runtime.panicTypeError())
    }
    return object
}

func builtinObject_isFrozen(call FunctionCall) Value {
    object := call.Argument(0)
    if object := object._object(); object != nil {
        if object.extensible {
            return toValue_bool(false)
        }
        result := true
        object.enumerate(true, func(name string) bool {
            property := object.getProperty(name)
            if property.configurable() || property.writable() {
                result = false
            }
            return true
        })
        return toValue_bool(result)
    }
    panic(call.runtime.panicTypeError())
}

func builtinObject_freeze(call FunctionCall) Value {
    object := call.Argument(0)
    if object := object._object(); object != nil {
        object.enumerate(true, func(name string) bool {
            if property, update := object.getOwnProperty(name), false; nil != property {
                if property.isDataDescriptor() && property.writable() {
                    property.writeOff()
                    update = true
                }
                if property.configurable() {
                    property.configureOff()
                    update = true
                }
                if update {
                    object.defineOwnProperty(name, *property, true)
                }
            }
            return true
        })
        object.extensible = false
    } else {
        panic(call.runtime.panicTypeError())
    }
    return object
}

func builtinObject_keys(call FunctionCall) Value {
    if object, keys := call.Argument(0)._object(), []Value(nil); nil != object {
        object.enumerate(false, func(name string) bool {
            keys = append(keys, toValue_string(name))
            return true
        })
        return toValue_object(call.runtime.newArrayOf(keys))
    }
    panic(call.runtime.panicTypeError())
}

func builtinObject_getOwnPropertyNames(call FunctionCall) Value {
    if object, propertyNames := call.Argument(0)._object(), []Value(nil); nil != object {
        object.enumerate(true, func(name string) bool {
            if object.hasOwnProperty(name) {
                propertyNames = append(propertyNames, toValue_string(name))
            }
            return true
        })
        return toValue_object(call.runtime.newArrayOf(propertyNames))
    }
    panic(call.runtime.panicTypeError())
}