Index: generic/xotcl.c =================================================================== diff -u -rbffe84bd5dccc0ed0d466bbf2d93bac783d49796 -r7c7a27874dbe5bb88a4261eef778b7fd29979761 --- generic/xotcl.c (.../xotcl.c) (revision bffe84bd5dccc0ed0d466bbf2d93bac783d49796) +++ generic/xotcl.c (.../xotcl.c) (revision 7c7a27874dbe5bb88a4261eef778b7fd29979761) @@ -7810,22 +7810,50 @@ XOTCLINLINE static int changeClass(Tcl_Interp *interp, XOTclObject *obj, XOTclClass *cl) { - assert(obj); + assert(obj); + + if (cl != obj->cl) { + if (IsMetaClass(interp, cl)) { + /* Do not allow upgrading from a class to a meta-class (in + other words, don't make an object to a class). To allow + this, it would be necessary to reallocate the base + structures. + */ + if (!IsMetaClass(interp, obj->cl)) { + return XOTclVarErrMsg(interp, "cannot change class of object ", + ObjStr(obj->cmdName), + " to metaclass ", + ObjStr(cl->object.cmdName),(char *) NULL); + } + } else { + /* The target class is not a meta class. Changing meta-class to + meta-class, or class to class is fine, but downgrading requires + more work */ - if (cl != obj->cl) { - if (IsMetaClass(interp, cl) && !IsMetaClass(interp, obj->cl)) { - return XOTclVarErrMsg(interp, "cannot change class of object ", - ObjStr(obj->cmdName), - " to metaclass ", - ObjStr(cl->object.cmdName),(char *) NULL); - } - (void)RemoveInstance(obj, obj->cl); - AddInstance(obj, cl); + /*fprintf(stderr,"target class %s not a meta class, am i a class %d\n", + ObjStr(cl->object.cmdName), + XOTclObjectIsClass(obj) );*/ - MixinComputeDefined(interp, obj); - FilterComputeDefined(interp, obj); - } - return TCL_OK; + if (XOTclObjectIsClass(obj)) { + XOTclObjectClearClass(obj); + /* We are not done here yet. We have to clear the + class from class hierarchies etc., where an object + is not allowed (e.g class hierarchies, mixin lists, etc.) + + We have to prohibit "Class class Object" + */ + + /*XXX*/ + + } + } + (void)RemoveInstance(obj, obj->cl); + AddInstance(obj, cl); + + MixinComputeDefined(interp, obj); + FilterComputeDefined(interp, obj); + } + return TCL_OK; } Index: generic/xotclInt.h =================================================================== diff -u -rbfeda566de60595825c75d78632d42458bb6cb05 -r7c7a27874dbe5bb88a4261eef778b7fd29979761 --- generic/xotclInt.h (.../xotclInt.h) (revision bfeda566de60595825c75d78632d42458bb6cb05) +++ generic/xotclInt.h (.../xotclInt.h) (revision 7c7a27874dbe5bb88a4261eef778b7fd29979761) @@ -447,6 +447,8 @@ #define XOTclObjectSetClass(obj) \ (obj)->flags |= XOTCL_IS_CLASS +#define XOTclObjectClearClass(obj) \ + (obj)->flags &= ~XOTCL_IS_CLASS #define XOTclObjectIsClass(obj) \ ((obj)->flags & XOTCL_IS_CLASS) #define XOTclObjectToClass(obj) \ Index: tests/testx.xotcl =================================================================== diff -u -r34f178fae21c3cf3a2410c7b1986d3e6b84dcf42 -r7c7a27874dbe5bb88a4261eef778b7fd29979761 --- tests/testx.xotcl (.../testx.xotcl) (revision 34f178fae21c3cf3a2410c7b1986d3e6b84dcf42) +++ tests/testx.xotcl (.../testx.xotcl) (revision 7c7a27874dbe5bb88a4261eef778b7fd29979761) @@ -3185,6 +3185,31 @@ ::errorCheck [Object ismetaclass M] 1 "is metaclass 1" ::errorCheck [Object ismetaclass C] 0 "is metaclass 0" + Class X + ::errorCheck [Object ismetaclass X] 0 "is metaclass 0" + ::errorCheck [X isclass] 1 "is isclass 1" + ::errorCheck [Class info instances X] ::X "is an instance of Class" + X class Object + ::errorCheck [X isclass] 0 "is isclass 0" + ::errorCheck [Class info instances X] "" "is not an instance of Class" + X destroy + + Class M -superclass Class + M create m1 + ::errorCheck [Object ismetaclass M] 1 "is metaclass 1" + ::errorCheck [M isclass] 1 "is isclass 1" + ::errorCheck [Class info instances M] ::M "is an instance of Class" + ::errorCheck [m1 info class] ::M "m1 is an instance of the meta-class" + ::errorCheck [m1 isclass] 1 "m1 is isclass 1" + M class Object + ::errorCheck [Object ismetaclass M] 0 "is metaclass 1" + ::errorCheck [M isclass] 0 "is isclass 0" + ::errorCheck [Class info instances M] "" "is not an instance of Class" + ::errorCheck [m1 info class] ::M "m1 is an instance of the meta-class" + ::errorCheck [m1 isclass] 1 "m1 is isclass 1" + + # to be completed XXX + Class C -parameter {number name} C instproc test {} { my instvar {number x} name