Index: generic/gentclAPI.decls =================================================================== diff -u -r477c12e1b0f192ab18de415e30001ea151d7ddda -r033a6b832c7cc7d99894422d63d9ff944c09c35d --- generic/gentclAPI.decls (.../gentclAPI.decls) (revision 477c12e1b0f192ab18de415e30001ea151d7ddda) +++ generic/gentclAPI.decls (.../gentclAPI.decls) (revision 033a6b832c7cc7d99894422d63d9ff944c09c35d) @@ -208,7 +208,8 @@ classMethod instinvar XOTclCInvariantsMethod { {-argName "invariantlist" -required 1 -type tclobj} } -classMethod instmixinguard XOTclCInstMixinGuardMethod { +classMethod mixinguard XOTclCMixinGuardMethod { + {-argName "-per-object" -type switch} {-argName "mixin" -required 1} {-argName "guard" -required 1 -type tclobj} } Index: generic/predefined.h =================================================================== diff -u -r477c12e1b0f192ab18de415e30001ea151d7ddda -r033a6b832c7cc7d99894422d63d9ff944c09c35d --- generic/predefined.h (.../predefined.h) (revision 477c12e1b0f192ab18de415e30001ea151d7ddda) +++ generic/predefined.h (.../predefined.h) (revision 033a6b832c7cc7d99894422d63d9ff944c09c35d) @@ -57,7 +57,7 @@ "::xotcl::alias ::xotcl2::classInfo [namespace tail $cmd] $cmd}\n" "foreach cmd [info command ::xotcl::cmd::ClassInfo::*] {\n" "set cmdName [namespace tail $cmd]\n" -"if {$cmdName in [list \"instfilter\" \"instforward\" \"instmixin\" \"instparams\"]} continue\n" +"if {$cmdName in [list \"instfilter\" \"instforward\" \"instmixin\" \"instmixinguard\" \"instparams\"]} continue\n" "::xotcl::alias ::xotcl2::classInfo $cmdName $cmd}\n" "unset cmd\n" "Object forward info -onerror ::xotcl::infoError -verbose ::xotcl2::objectInfo %1 {%@2 %self}\n" Index: generic/predefined.xotcl =================================================================== diff -u -r477c12e1b0f192ab18de415e30001ea151d7ddda -r033a6b832c7cc7d99894422d63d9ff944c09c35d --- generic/predefined.xotcl (.../predefined.xotcl) (revision 477c12e1b0f192ab18de415e30001ea151d7ddda) +++ generic/predefined.xotcl (.../predefined.xotcl) (revision 033a6b832c7cc7d99894422d63d9ff944c09c35d) @@ -124,7 +124,7 @@ } foreach cmd [info command ::xotcl::cmd::ClassInfo::*] { set cmdName [namespace tail $cmd] - if {$cmdName in [list "instfilter" "instforward" "instmixin" "instparams"]} continue + if {$cmdName in [list "instfilter" "instforward" "instmixin" "instmixinguard" "instparams"]} continue ::xotcl::alias ::xotcl2::classInfo $cmdName $cmd } unset cmd Index: generic/tclAPI.h =================================================================== diff -u -r477c12e1b0f192ab18de415e30001ea151d7ddda -r033a6b832c7cc7d99894422d63d9ff944c09c35d --- generic/tclAPI.h (.../tclAPI.h) (revision 477c12e1b0f192ab18de415e30001ea151d7ddda) +++ generic/tclAPI.h (.../tclAPI.h) (revision 033a6b832c7cc7d99894422d63d9ff944c09c35d) @@ -94,10 +94,10 @@ static int XOTclCDeallocMethodStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv []); static int XOTclCForwardMethodStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv []); static int XOTclCInstFilterGuardMethodStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv []); -static int XOTclCInstMixinGuardMethodStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv []); static int XOTclCInvalidateObjectParameterMethodStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv []); static int XOTclCInvariantsMethodStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv []); static int XOTclCMethodMethodStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv []); +static int XOTclCMixinGuardMethodStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv []); static int XOTclCNewMethodStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv []); static int XOTclCRecreateMethodStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv []); static int XOTclCSetterMethodStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv []); @@ -191,10 +191,10 @@ static int XOTclCDeallocMethod(Tcl_Interp *interp, XOTclClass *cl, Tcl_Obj *object); static int XOTclCForwardMethod(Tcl_Interp *interp, XOTclClass *cl, int withPer_object, Tcl_Obj *name, Tcl_Obj *withDefault, int withEarlybinding, Tcl_Obj *withMethodprefix, int withObjscope, Tcl_Obj *withOnerror, int withVerbose, Tcl_Obj *target, int nobjc, Tcl_Obj *CONST nobjv[]); static int XOTclCInstFilterGuardMethod(Tcl_Interp *interp, XOTclClass *cl, char *filter, Tcl_Obj *guard); -static int XOTclCInstMixinGuardMethod(Tcl_Interp *interp, XOTclClass *cl, char *mixin, Tcl_Obj *guard); static int XOTclCInvalidateObjectParameterMethod(Tcl_Interp *interp, XOTclClass *cl); static int XOTclCInvariantsMethod(Tcl_Interp *interp, XOTclClass *cl, Tcl_Obj *invariantlist); static int XOTclCMethodMethod(Tcl_Interp *interp, XOTclClass *cl, int withInner_namespace, int withPer_object, int withProtected, Tcl_Obj *name, Tcl_Obj *args, Tcl_Obj *body, Tcl_Obj *withPrecondition, Tcl_Obj *withPostcondition); +static int XOTclCMixinGuardMethod(Tcl_Interp *interp, XOTclClass *cl, int withPer_object, char *mixin, Tcl_Obj *guard); static int XOTclCNewMethod(Tcl_Interp *interp, XOTclClass *cl, XOTclObject *withChildof, int nobjc, Tcl_Obj *CONST nobjv[]); static int XOTclCRecreateMethod(Tcl_Interp *interp, XOTclClass *cl, Tcl_Obj *name, int objc, Tcl_Obj *CONST objv[]); static int XOTclCSetterMethod(Tcl_Interp *interp, XOTclClass *cl, int withPer_object, char *name); @@ -289,10 +289,10 @@ XOTclCDeallocMethodIdx, XOTclCForwardMethodIdx, XOTclCInstFilterGuardMethodIdx, - XOTclCInstMixinGuardMethodIdx, XOTclCInvalidateObjectParameterMethodIdx, XOTclCInvariantsMethodIdx, XOTclCMethodMethodIdx, + XOTclCMixinGuardMethodIdx, XOTclCNewMethodIdx, XOTclCRecreateMethodIdx, XOTclCSetterMethodIdx, @@ -524,26 +524,6 @@ } static int -XOTclCInstMixinGuardMethodStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { - parseContext pc; - XOTclClass *cl = XOTclObjectToClass(clientData); - if (!cl) return XOTclObjErrType(interp, objv[0], "Class"); - if (ArgumentParse(interp, objc, objv, (XOTclObject *) cl, objv[0], - method_definitions[XOTclCInstMixinGuardMethodIdx].paramDefs, - method_definitions[XOTclCInstMixinGuardMethodIdx].nrParameters, - &pc) != TCL_OK) { - return TCL_ERROR; - } else { - char *mixin = (char *)pc.clientData[0]; - Tcl_Obj *guard = (Tcl_Obj *)pc.clientData[1]; - - parseContextRelease(&pc); - return XOTclCInstMixinGuardMethod(interp, cl, mixin, guard); - - } -} - -static int XOTclCInvalidateObjectParameterMethodStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { parseContext pc; XOTclClass *cl = XOTclObjectToClass(clientData); @@ -608,6 +588,27 @@ } static int +XOTclCMixinGuardMethodStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { + parseContext pc; + XOTclClass *cl = XOTclObjectToClass(clientData); + if (!cl) return XOTclObjErrType(interp, objv[0], "Class"); + if (ArgumentParse(interp, objc, objv, (XOTclObject *) cl, objv[0], + method_definitions[XOTclCMixinGuardMethodIdx].paramDefs, + method_definitions[XOTclCMixinGuardMethodIdx].nrParameters, + &pc) != TCL_OK) { + return TCL_ERROR; + } else { + int withPer_object = (int )pc.clientData[0]; + char *mixin = (char *)pc.clientData[1]; + Tcl_Obj *guard = (Tcl_Obj *)pc.clientData[2]; + + parseContextRelease(&pc); + return XOTclCMixinGuardMethod(interp, cl, withPer_object, mixin, guard); + + } +} + +static int XOTclCNewMethodStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { parseContext pc; XOTclClass *cl = XOTclObjectToClass(clientData); @@ -2340,10 +2341,6 @@ {"filter", 1, 0, convertToString}, {"guard", 1, 0, convertToTclobj}} }, -{"::xotcl::cmd::Class::instmixinguard", XOTclCInstMixinGuardMethodStub, 2, { - {"mixin", 1, 0, convertToString}, - {"guard", 1, 0, convertToTclobj}} -}, {"::xotcl::cmd::Class::invalidateobjectparameter", XOTclCInvalidateObjectParameterMethodStub, 0, { } }, @@ -2360,6 +2357,11 @@ {"-precondition", 0, 1, convertToTclobj}, {"-postcondition", 0, 1, convertToTclobj}} }, +{"::xotcl::cmd::Class::mixinguard", XOTclCMixinGuardMethodStub, 3, { + {"-per-object", 0, 0, convertToBoolean}, + {"mixin", 1, 0, convertToString}, + {"guard", 1, 0, convertToTclobj}} +}, {"::xotcl::cmd::Class::new", XOTclCNewMethodStub, 2, { {"-childof", 0, 1, convertToObject}, {"args", 0, 0, convertToNothing}} Index: generic/xotcl.c =================================================================== diff -u -r477c12e1b0f192ab18de415e30001ea151d7ddda -r033a6b832c7cc7d99894422d63d9ff944c09c35d --- generic/xotcl.c (.../xotcl.c) (revision 477c12e1b0f192ab18de415e30001ea151d7ddda) +++ generic/xotcl.c (.../xotcl.c) (revision 033a6b832c7cc7d99894422d63d9ff944c09c35d) @@ -12357,6 +12357,36 @@ return TCL_OK; } +static int XOTclCMixinGuardMethod(Tcl_Interp *interp, XOTclClass *cl, int withPer_object, char *mixin, Tcl_Obj *guard) { + XOTclClassOpt *opt = cl->opt; + XOTclCmdList *h; + + if (withPer_object) { + return XOTclOMixinGuardMethod(interp, &cl->object, mixin, guard); + } + + if (opt && opt->instmixins) { + XOTclClass *mixinCl = XOTclpGetClass(interp, mixin); + Tcl_Command mixinCmd = NULL; + if (mixinCl) { + mixinCmd = Tcl_GetCommandFromObj(interp, mixinCl->object.cmdName); + } + if (mixinCmd) { + h = CmdListFindCmdInList(mixinCmd, opt->instmixins); + if (h) { + if (h->clientData) + GuardDel((XOTclCmdList*) h); + GuardAdd(interp, h, guard); + MixinInvalidateObjOrders(interp, cl); + return TCL_OK; + } + } + } + + return XOTclVarErrMsg(interp, "Instmixinguard: can't find mixin ", + mixin, " on ", className(cl), (char *) NULL); +} + static int XOTclCInstMixinGuardMethod(Tcl_Interp *interp, XOTclClass *cl, char *mixin, Tcl_Obj *guard) { XOTclClassOpt *opt = cl->opt; XOTclCmdList *h; Index: library/lib/xotcl1.xotcl =================================================================== diff -u -rb708f296be8c5cbd3e4daa959713483dbdfdfd82 -r033a6b832c7cc7d99894422d63d9ff944c09c35d --- library/lib/xotcl1.xotcl (.../xotcl1.xotcl) (revision b708f296be8c5cbd3e4daa959713483dbdfdfd82) +++ library/lib/xotcl1.xotcl (.../xotcl1.xotcl) (revision 033a6b832c7cc7d99894422d63d9ff944c09c35d) @@ -332,14 +332,19 @@ -object {%::xotcl::dispatch [::xotcl::self] -objscope ::subst [::xotcl::self]::slot} # # define proc and instproc in terms of method + # define forward and instforward in terms of forward + # define parametercmd and instparametercmd in terms of setter + # define parametercmd and instparametercmd in terms of setter + # define mixinguard and instmixinguard in terms of mixinguard # Object method proc {name arglist body precondition:optional postcondition:optional} { set cmd [list my method $name $arglist $body] if {[info exists precondition]} {lappend cmd -precondition $precondition} if {[info exists postcondition]} {lappend cmd -postcondition $postcondition} eval $cmd } - Object forward parametercmd %self setter + ::xotcl::alias Object parametercmd ::xotcl::cmd::Object::setter + Class method proc {name arglist body precondition:optional postcondition:optional} { set cmd [list my method -per-object $name $arglist $body] if {[info exists precondition]} {lappend cmd -precondition $precondition} @@ -352,15 +357,16 @@ if {[info exists postcondition]} {lappend cmd -postcondition $postcondition} eval $cmd } - Class forward parametercmd %self setter -per-object - Class forward instparametercmd %self setter + ::xotcl::alias Class instparametercmd ::xotcl::cmd::Class::setter + ::xotcl::alias Class parametercmd ::xotcl::cmd::Object::setter + ::xotcl::alias Class instmixinguard ::xotcl::cmd::Class::mixinguard + ::xotcl::alias Class mixinguard ::xotcl::cmd::Object::mixinguard - # we are changing the the semantics from forward -> instforward - ::xotcl::alias Class instforward ::xotcl::cmd::Class::forward - ::xotcl::alias Class forward ::xotcl::cmd::Object::forward - #Class method forward {name args} { - # ::xotcl::dispatch [self] ::xotcl::cmd::Class::forward -per-object $name {*}$args - #} + # we are changing the the semantics from forward -> instforward, + # this has to be done at the end to avoid confusion with the + # previous forward invocation in this script. + ::xotcl::alias Class instforward ::xotcl::cmd::Class::forward + ::xotcl::alias Class forward ::xotcl::cmd::Object::forward Object method abstract {methtype methname arglist} { if {$methtype ne "proc" && $methtype ne "instproc" && $methtype ne "method"} {