/*
    This file is part of the WebKit open source project.
    This file has been generated by generate-bindings.pl. DO NOT MODIFY!

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to
    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
    Boston, MA 02110-1301, USA.
*/

#include "config.h"
#include "JSXPathExpression.h"

#include "ExceptionCode.h"
#include "JSDOMBinding.h"
#include "JSDOMConstructor.h"
#include "JSDOMConvert.h"
#include "JSNode.h"
#include "JSXPathResult.h"
#include "XPathResult.h"
#include <runtime/Error.h>
#include <runtime/FunctionPrototype.h>
#include <wtf/GetPtr.h>

using namespace JSC;

namespace WebCore {

// Functions

JSC::EncodedJSValue JSC_HOST_CALL jsXPathExpressionPrototypeFunctionEvaluate(JSC::ExecState*);

// Attributes

JSC::EncodedJSValue jsXPathExpressionConstructor(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
bool setJSXPathExpressionConstructor(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);

class JSXPathExpressionPrototype : public JSC::JSNonFinalObject {
public:
    typedef JSC::JSNonFinalObject Base;
    static JSXPathExpressionPrototype* create(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure)
    {
        JSXPathExpressionPrototype* ptr = new (NotNull, JSC::allocateCell<JSXPathExpressionPrototype>(vm.heap)) JSXPathExpressionPrototype(vm, globalObject, structure);
        ptr->finishCreation(vm);
        return ptr;
    }

    DECLARE_INFO;
    static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
    {
        return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info());
    }

private:
    JSXPathExpressionPrototype(JSC::VM& vm, JSC::JSGlobalObject*, JSC::Structure* structure)
        : JSC::JSNonFinalObject(vm, structure)
    {
    }

    void finishCreation(JSC::VM&);
};

typedef JSDOMConstructorNotConstructable<JSXPathExpression> JSXPathExpressionConstructor;

template<> JSValue JSXPathExpressionConstructor::prototypeForStructure(JSC::VM& vm, const JSDOMGlobalObject& globalObject)
{
    UNUSED_PARAM(vm);
    return globalObject.functionPrototype();
}

template<> void JSXPathExpressionConstructor::initializeProperties(VM& vm, JSDOMGlobalObject& globalObject)
{
    putDirect(vm, vm.propertyNames->prototype, JSXPathExpression::prototype(vm, &globalObject), DontDelete | ReadOnly | DontEnum);
    putDirect(vm, vm.propertyNames->name, jsNontrivialString(&vm, String(ASCIILiteral("XPathExpression"))), ReadOnly | DontEnum);
    putDirect(vm, vm.propertyNames->length, jsNumber(0), ReadOnly | DontEnum);
}

template<> const ClassInfo JSXPathExpressionConstructor::s_info = { "XPathExpression", &Base::s_info, 0, CREATE_METHOD_TABLE(JSXPathExpressionConstructor) };

/* Hash table for prototype */

static const HashTableValue JSXPathExpressionPrototypeTableValues[] =
{
    { "constructor", DontEnum, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsXPathExpressionConstructor), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSXPathExpressionConstructor) } },
    { "evaluate", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsXPathExpressionPrototypeFunctionEvaluate), (intptr_t) (0) } },
};

const ClassInfo JSXPathExpressionPrototype::s_info = { "XPathExpressionPrototype", &Base::s_info, 0, CREATE_METHOD_TABLE(JSXPathExpressionPrototype) };

void JSXPathExpressionPrototype::finishCreation(VM& vm)
{
    Base::finishCreation(vm);
    reifyStaticProperties(vm, JSXPathExpressionPrototypeTableValues, *this);
}

const ClassInfo JSXPathExpression::s_info = { "XPathExpression", &Base::s_info, 0, CREATE_METHOD_TABLE(JSXPathExpression) };

JSXPathExpression::JSXPathExpression(Structure* structure, JSDOMGlobalObject& globalObject, Ref<XPathExpression>&& impl)
    : JSDOMWrapper<XPathExpression>(structure, globalObject, WTFMove(impl))
{
}

JSObject* JSXPathExpression::createPrototype(VM& vm, JSGlobalObject* globalObject)
{
    return JSXPathExpressionPrototype::create(vm, globalObject, JSXPathExpressionPrototype::createStructure(vm, globalObject, globalObject->objectPrototype()));
}

JSObject* JSXPathExpression::prototype(VM& vm, JSGlobalObject* globalObject)
{
    return getDOMPrototype<JSXPathExpression>(vm, globalObject);
}

void JSXPathExpression::destroy(JSC::JSCell* cell)
{
    JSXPathExpression* thisObject = static_cast<JSXPathExpression*>(cell);
    thisObject->JSXPathExpression::~JSXPathExpression();
}

EncodedJSValue jsXPathExpressionConstructor(ExecState* state, EncodedJSValue thisValue, PropertyName)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    JSXPathExpressionPrototype* domObject = jsDynamicCast<JSXPathExpressionPrototype*>(JSValue::decode(thisValue));
    if (UNLIKELY(!domObject))
        return throwVMTypeError(state, throwScope);
    return JSValue::encode(JSXPathExpression::getConstructor(state->vm(), domObject->globalObject()));
}

bool setJSXPathExpressionConstructor(ExecState* state, EncodedJSValue thisValue, EncodedJSValue encodedValue)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    JSValue value = JSValue::decode(encodedValue);
    JSXPathExpressionPrototype* domObject = jsDynamicCast<JSXPathExpressionPrototype*>(JSValue::decode(thisValue));
    if (UNLIKELY(!domObject)) {
        throwVMTypeError(state, throwScope);
        return false;
    }
    // Shadowing a built-in constructor
    return domObject->putDirect(state->vm(), state->propertyNames().constructor, value);
}

JSValue JSXPathExpression::getConstructor(VM& vm, const JSGlobalObject* globalObject)
{
    return getDOMConstructor<JSXPathExpressionConstructor>(vm, *jsCast<const JSDOMGlobalObject*>(globalObject));
}

EncodedJSValue JSC_HOST_CALL jsXPathExpressionPrototypeFunctionEvaluate(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSXPathExpression*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "XPathExpression", "evaluate");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSXPathExpression::info());
    auto& impl = castedThis->wrapped();
    ExceptionCode ec = 0;
    Node* contextNode = nullptr;
    if (!state->argument(0).isUndefinedOrNull()) {
        contextNode = JSNode::toWrapped(state->uncheckedArgument(0));
        if (UNLIKELY(!contextNode))
            return throwArgumentTypeError(*state, throwScope, 0, "contextNode", "XPathExpression", "evaluate", "Node");
    }
    auto type = convert<uint16_t>(*state, state->argument(1), NormalConversion);
    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
    XPathResult* inResult = nullptr;
    if (!state->argument(2).isUndefinedOrNull()) {
        inResult = JSXPathResult::toWrapped(state->uncheckedArgument(2));
        if (UNLIKELY(!inResult))
            return throwArgumentTypeError(*state, throwScope, 2, "inResult", "XPathExpression", "evaluate", "XPathResult");
    }
    JSValue result = toJS(state, castedThis->globalObject(), impl.evaluate(WTFMove(contextNode), WTFMove(type), WTFMove(inResult), ec));

    setDOMException(state, throwScope, ec);
    return JSValue::encode(result);
}

bool JSXPathExpressionOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor)
{
    UNUSED_PARAM(handle);
    UNUSED_PARAM(visitor);
    return false;
}

void JSXPathExpressionOwner::finalize(JSC::Handle<JSC::Unknown> handle, void* context)
{
    auto* jsXPathExpression = jsCast<JSXPathExpression*>(handle.slot()->asCell());
    auto& world = *static_cast<DOMWrapperWorld*>(context);
    uncacheWrapper(world, &jsXPathExpression->wrapped(), jsXPathExpression);
}

JSC::JSValue toJSNewlyCreated(JSC::ExecState*, JSDOMGlobalObject* globalObject, Ref<XPathExpression>&& impl)
{
#if COMPILER(CLANG)
    // If you hit this failure the interface definition has the ImplementationLacksVTable
    // attribute. You should remove that attribute. If the class has subclasses
    // that may be passed through this toJS() function you should use the SkipVTableValidation
    // attribute to XPathExpression.
    static_assert(!__is_polymorphic(XPathExpression), "XPathExpression is polymorphic but the IDL claims it is not");
#endif
    return createWrapper<XPathExpression>(globalObject, WTFMove(impl));
}

JSC::JSValue toJS(JSC::ExecState* state, JSDOMGlobalObject* globalObject, XPathExpression& impl)
{
    return wrap(state, globalObject, impl);
}

XPathExpression* JSXPathExpression::toWrapped(JSC::JSValue value)
{
    if (auto* wrapper = jsDynamicCast<JSXPathExpression*>(value))
        return &wrapper->wrapped();
    return nullptr;
}

}
