|
|
/* * This file is part of the KDE libraries * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) * * 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., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #ifndef _KJS_OBJECT_H_ #define _KJS_OBJECT_H_ #include <stdlib.h> #include "ustring.h" /** * @short Main namespace */ namespace KJS { /** * Types of classes derived from KJSO */ enum Type { // main types AbstractType = 1, UndefinedType, NullType, BooleanType, NumberType, StringType, ObjectType, HostType, ReferenceType, CompletionType, // extended types FunctionType, InternalFunctionType, DeclaredFunctionType, AnonymousFunctionType, ConstructorType, ActivationType }; /** * Property attributes. */ enum Attribute { None = 0, ReadOnly = 1 << 1, DontEnum = 1 << 2, DontDelete = 1 << 3, Internal = 1 << 4 }; /** * Types of classes derived from @ref Object. */ enum Class { UndefClass, ArrayClass, StringClass, BooleanClass, NumberClass, ObjectClass, DateClass, RegExpClass, ErrorClass, FunctionClass }; /** * Completion types. */ enum Compl { Normal, Break, Continue, ReturnValue, Throw }; /** * Error codes. */ enum ErrorType { NoError = 0, GeneralError, EvalError, RangeError, ReferenceError, SyntaxError, TypeError, URIError }; extern const double NaN; extern const double Inf; // forward declarations class Imp; class Boolean; class Number; class String; class Object; struct Property; class PropList; class List; /** * @short Type information. */ struct TypeInfo { /** * A string denoting the type name. Example: "Number". */ const char *name; /** * One of the @ref KJS::Type enums. */ Type type; /** * Pointer to the type information of the base class. * NULL if there is none. */ const TypeInfo *base; /** * Additional specifier for your own use. */ int extra; /** * Reserved for future extensions (internal). */ void *dummy; }; /** * @short Main base class for every KJS object. */ class KJSO { friend class ElementNode; public: /** * Constructor. */ KJSO(); /** * @internal */ KJSO(Imp *d); /** * Copy constructor. */ KJSO(const KJSO &); /* * Assignment operator */ KJSO& operator=(const KJSO &); /** * Destructor. */ virtual ~KJSO(); /** * @return True if this object is null, i.e. if there is no data attached * to this object. Don't confuse this with the Null object. */ bool isNull() const; /** * @return True if this objects is of any other value than Undefined. */ bool isDefined() const; /** * @return the type of the object. One of the @ref KJS::Type enums. */ Type type() const; /** * Check whether object is of a certain type * @param t type to check for */ bool isA(Type t) const { return (type() == t); } /** * Check whether object is of a certain type. Allows checking of * host objects, too. * @param type name (Number, Boolean etc.) */ bool isA(const char *s) const; /** * Use this method when checking for objects. It's safer than checking * for a single object type with @ref isA(). */ bool isObject() const; /** * Examine the inheritance structure of this object. * @param t Name of the base class. * @return True if object is of type t or a derived from such a type. */ bool derivedFrom(const char *s) const; /** * @return Conversion to primitive type (Undefined, Boolean, Number * or String) * @param preferred Optional hint. Either StringType or NumberType. */ KJSO toPrimitive(Type preferred = UndefinedType) const; // ECMA 9.1 /** * @return Conversion to Boolean type. */ Boolean toBoolean() const; // ECMA 9.2 /** * @return Conversion to Number type. */ Number toNumber() const; // ECMA 9.3 /** * @return Conversion to double. 0.0 if conversion failed. */ double round() const; /** * @return Conversion to Number type containing an integer value. */ Number toInteger() const; // ECMA 9.4 /** * @return Conversion to signed integer value. */ int toInt32() const; // ECMA 9.5 /** * @return Conversion to unsigned integer value. */ unsigned int toUInt32() const; // ECMA 9.6 /** * @return Conversion to unsigned short value. */ unsigned short toUInt16() const; // ECMA 9.7 /** * @return Conversion to String type. */ String toString() const; // ECMA 9.8 /** * @return Conversion to Object type. */ Object toObject() const; // ECMA 9.9 // Properties /** * Set the internal [[prototype]] property of this object. * @param p A prototype object. */ void setPrototype(const KJSO& p); /** * @return The internal [[prototype]] property. */ KJSO prototype() const; /** * The internal [[Get]] method. * @return The value of property p. */ KJSO get(const UString &p) const; /** * The internal [[HasProperty]] method. * @param p Property name. * @param recursive Indicates whether prototypes are searched as well. * @return Boolean value indicating whether the object already has a * member with the given name p. */ bool hasProperty(const UString &p, bool recursive = true) const; /** * The internal [[Put]] method. Sets the specified property to the value v. * @param p Property name. * @param v Value. */ void put(const UString &p, const KJSO& v); /** * The internal [[CanPut]] method. * @param p Property name. * @return A boolean value indicating whether a [[Put]] operation with * p succeed. */ bool canPut(const UString &p) const; /** * The internal [[Delete]] method. Removes the specified property from * the object. * @param p Property name. * @return True if the property was deleted successfully or didn't exist * in the first place. False if the DontDelete attribute was set. */ bool deleteProperty(const UString &p); /** * Same as above put() method except the additional attribute. Right now, * this only works with native types as Host Objects don't reimplement * this method. * @param attr One of @ref KJS::Attribute. */ void put(const UString &p, const KJSO& v, int attr); /** * Convenience function for adding a Number property constructed from * a double value. */ void put(const UString &p, double d, int attr = None); /** * Convenience function for adding a Number property constructed from * an integer value. */ void put(const UString &p, int i, int attr = None); /** * Convenience function for adding a Number property constructed from * an unsigned integer value. */ void put(const UString &p, unsigned int u, int attr = None); /** * Reference method. * @return Reference base if object is a reference. Throws * a ReferenceError otherwise. */ KJSO getBase() const; /** * Reference method. * @return Property name of a reference. Null string if object is not * a reference. */ UString getPropertyName() const; /** * Reference method. * @return Referenced value. This object if no reference. */ KJSO getValue(); /** * Reference method. Set referenced value to v. */ ErrorType putValue(const KJSO& v); /** * @return True if object supports @ref executeCall() method. That's the * case for all objects derived from FunctionType. */ bool implementsCall() const; /** * Execute function implemented via the @ref Function::execute() method. * * Note: check availability via @ref implementsCall() beforehand. * @param thisV Object serving as the 'this' value. * @param args Pointer to the list of arguments or null. * @return Result of the function call. */ KJSO executeCall(const KJSO &thisV, const List *args); /** * Set this object's constructor. */ void setConstructor(KJSO c); /** * @return A Pointer to the internal implementation. */ Imp *imp() const { return rep; } #ifdef KJS_DEBUG_MEM /** * @internal */ static int count; #endif protected: /** * Pointer to the internal implementation. */ Imp *rep; private: void putArrayElement(const UString &p, const KJSO &v); }; // end of KJSO /** * @short Base for all implementation classes. */ class Imp { friend class KJSO; friend class Collector; friend class ForInNode; public: Imp(); public: virtual KJSO toPrimitive(Type preferred = UndefinedType) const; // ECMA 9.1 virtual Boolean toBoolean() const; // ECMA 9.2 virtual Number toNumber() const; // ECMA 9.3 virtual String toString() const; // ECMA 9.8 virtual Object toObject() const; // ECMA 9.9 // properties virtual KJSO get(const UString &p) const; virtual bool hasProperty(const UString &p, bool recursive = true) const; virtual void put(const UString &p, const KJSO& v); void put(const UString &p, const KJSO& v, int attr); virtual bool canPut(const UString &p) const; virtual bool deleteProperty(const UString &p); virtual KJSO defaultValue(Type hint) const; bool implementsCall() const; /** * @internal Reserved for mark & sweep garbage collection */ virtual void mark(Imp *imp = 0L); Type type() const { return typeInfo()->type; } /** * @return The TypeInfo struct describing this object. */ virtual const TypeInfo* typeInfo() const { return &info; } void setPrototype(const KJSO& p); void setConstructor(const KJSO& c); void* operator new(size_t); void operator delete(void*, size_t); #ifdef KJS_DEBUG_MEM /** * @internal */ static int count; #endif protected: virtual ~Imp(); private: Imp(const Imp&); Imp& operator=(const Imp&); void putArrayElement(const UString &p, const KJSO& v); /** * Get the property names for this object. To be used by for .. in loops * @return The (pointer to the) first element of a PropList, to be deleted * by the caller, or 0 if there are no enumerable properties */ PropList *getPropList(PropList *first = 0L, PropList *last = 0L) const; // reference counting mechanism inline Imp* ref() { refcount++; return this; } inline bool deref() { return (!--refcount); } public: unsigned int refcount; private: Property *prop; Imp *proto; static const TypeInfo info; // reserved for memory managment Imp *prev, *next; // for future extensions class ImpInternal; ImpInternal *internal; }; /** * @short General implementation class for Objects */ class ObjectImp : public Imp { friend class Object; public: ObjectImp(Class c); ObjectImp(Class c, const KJSO &v); ObjectImp(Class c, const KJSO &v, const KJSO &p); virtual ~ObjectImp(); virtual KJSO toPrimitive(Type preferred = UndefinedType) const; virtual Boolean toBoolean() const; virtual Number toNumber() const; virtual String toString() const; virtual Object toObject() const; virtual const TypeInfo* typeInfo() const { return &info; } static const TypeInfo info; /** * @internal Reimplemenation of @ref Imp::mark(). */ virtual void mark(Imp *imp = 0L); private: Class cl; Imp *val; }; /** * @short Object class encapsulating an internal value. */ class Object : public KJSO { public: Object(Imp *d); Object(Class c = UndefClass); Object(Class c, const KJSO& v); Object(Class c, const KJSO& v, const Object& p); virtual ~Object(); void setClass(Class c); Class getClass() const; void setInternalValue(const KJSO& v); KJSO internalValue(); static Object create(Class c); static Object create(Class c, const KJSO& val); static Object create(Class c, const KJSO& val, const Object &p); static Object dynamicCast(const KJSO &obj); }; /** * @short Implementation base class for Host Objects. */ class HostImp : public Imp { public: virtual ~HostImp(); virtual const TypeInfo* typeInfo() const { return &info; } virtual Boolean toBoolean() const; static const TypeInfo info; }; class KJScriptImp; /** * The Global object represents the global namespace. It holds the native * objects like String and functions like eval(). * * It also serves as a container for variables created by the user, i.e. * the statement * <pre> * var i = 2; * </pre> * will basically perform a Global::current().put("i", Number(2)); operation. * * @short Unique global object containing initial native properties. */ class Global : public Object { friend class KJScriptImp; public: /** * Constructs a Global object. This is done by the interpreter once and * there should be no need to create an instance on your own. Usually, * you'll just want to access the current instance. * For example like this: * <pre> * Global global(Global::current()); * KJSO proto = global.objectPrototype(); * </pre> */ Global(); /** * Destruct the Global object. */ virtual ~Global(); /** * @return A reference to the Global object belonging to the current * interpreter instance. */ static Global current(); /** * @return A handle to Object.prototype. */ KJSO objectPrototype() const; /** * @return A handle to Function.prototype. */ KJSO functionPrototype() const; /** * Set a filter object that will intercept all put() and get() calls * to the global object. If this object returns Undefined on get() the * request will be passed on the global object. */ void setFilter(const KJSO &f); /** * Return a handle to the filter object (see @ref setFilter()). * Null if no filter has been installed. */ KJSO filter() const; private: Global(void *); void init(); }; /** * @short Factory methods for error objects. */ class Error { public: /** * Factory method for error objects. The error will be registered globally * and the execution will continue as if a "throw" statement was * encountered. * @param e Type of error. * @param m Optional error message. * @param l Optional line number. */ static KJSO create(ErrorType e, const char *m = 0, int l = -1); /** * Same as above except the different return type (which is not casted * here). */ static Object createObject(ErrorType e, const char *m = 0, int l = -1); }; }; // namespace #endif
Generated by: dfaure on Tue Feb 27 12:47:36 2001, using kdoc 2.0a50. |