Index: generic/gentclAPI.decls =================================================================== diff -u -r8f79347327f3c5f73faf86e87ebd6c8306265fbb -rb708f296be8c5cbd3e4daa959713483dbdfdfd82 --- generic/gentclAPI.decls (.../gentclAPI.decls) (revision 8f79347327f3c5f73faf86e87ebd6c8306265fbb) +++ generic/gentclAPI.decls (.../gentclAPI.decls) (revision b708f296be8c5cbd3e4daa959713483dbdfdfd82) @@ -400,6 +400,12 @@ infoClassMethod instinvar XOTclClassInfoInstinvarMethod { {-argName "class" -required 1 -type class} } +infoClassMethod mixin XOTclClassInfoMixinMethod { + {-argName "class" -required 1 -type class} + {-argName "-closure"} + {-argName "-guards"} + {-argName "pattern" -type objpattern} +} infoClassMethod instmixin XOTclClassInfoInstmixinMethod { {-argName "class" -required 1 -type class} {-argName "-closure"} Index: generic/predefined.h =================================================================== diff -u -r8f79347327f3c5f73faf86e87ebd6c8306265fbb -rb708f296be8c5cbd3e4daa959713483dbdfdfd82 --- generic/predefined.h (.../predefined.h) (revision 8f79347327f3c5f73faf86e87ebd6c8306265fbb) +++ generic/predefined.h (.../predefined.h) (revision b708f296be8c5cbd3e4daa959713483dbdfdfd82) @@ -56,11 +56,15 @@ "::xotcl::alias ::xotcl2::objectInfo [namespace tail $cmd] $cmd\n" "::xotcl::alias ::xotcl2::classInfo [namespace tail $cmd] $cmd}\n" "foreach cmd [info command ::xotcl::cmd::ClassInfo::*] {\n" -"::xotcl::alias ::xotcl2::classInfo [namespace tail $cmd] $cmd}\n" +"set cmdName [namespace tail $cmd]\n" +"if {$cmdName in [list \"instfilter\" \"instforward\" \"instmixin\" \"instparams\"]} continue\n" +"puts stderr \"adding ::xotcl::alias ::xotcl2::classInfo $cmdName $cmd\"\n" +"::xotcl::alias ::xotcl2::classInfo $cmdName $cmd}\n" "unset cmd\n" -"Object forward info -onerror ::xotcl::infoError ::xotcl2::objectInfo %1 {%@2 %self}\n" -"Class forward info -onerror ::xotcl::infoError ::xotcl2::classInfo %1 {%@2 %self}\n" -"::xotcl::dispatch ::xotcl2::classInfo ::xotcl::cmd::Object::forward \"-per-object\" ::xotcl2::objectInfo {%@2 %1}\n" +"Object forward info -onerror ::xotcl::infoError -verbose ::xotcl2::objectInfo %1 {%@2 %self}\n" +"Class forward info -onerror ::xotcl::infoError -verbose ::xotcl2::classInfo %1 {%@2 %self}\n" +"::xotcl::dispatch ::xotcl2::classInfo ::xotcl::cmd::Object::forward \\\n" +"\"-per-object\" -verbose ::xotcl2::objectInfo {%@2 %1}\n" "proc ::xotcl::infoError msg {\n" "regsub -all \" \" $msg \"\" msg\n" "regsub -all \" \" $msg \"\" msg\n" @@ -190,6 +194,7 @@ "${.domain} invalidateobjectparameter\n" "::xotcl::dispatch ${.domain} ::xotcl::cmd::Class::forward \\\n" "{*}[expr {${.per-object} ? \"-per-object\" : \"\"}] ${.name} \\\n" +"-verbose \\\n" "-default [${.manager} defaultmethods] ${.manager} %1 %self \\\n" "{*}[expr {[info exists .forward-per-object] ? \"-per-object\" : \"\"}] \\\n" "%proc}}\n" @@ -200,11 +205,13 @@ "::xotcl::relation ::xotcl::InfoSlot superclass ::xotcl::Slot\n" "::xotcl::InfoSlot method get {obj -per-object:switch prop} {$obj info $prop}\n" "::xotcl::InfoSlot method add {obj -per-object:switch prop value {pos 0}} {\n" +"puts stderr infoslot-add-[self args]\n" "if {![set .multivalued]} {\n" "error \"Property $prop of ${.domain}->$obj ist not multivalued\"}\n" "puts stderr \"adding infoslot: $obj $prop [linsert [$obj info $prop] $pos $value]\"\n" "$obj $prop [linsert [$obj info $prop] $pos $value]}\n" "::xotcl::InfoSlot method delete {-nocomplain:switch obj prop value} {\n" +"puts stderr infoslot-delete-[self args]\n" "set old [$obj info $prop]\n" "if {[string first * $value] > -1 || [string first \\[ $value] > -1} {\n" "if {${.elementtype} ne \"\" && ![string match ::* $value]} {\n" @@ -213,7 +220,7 @@ "if {[string first :: $value] == -1} {\n" "if {![::xotcl::is $value object]} {\n" "error \"$value does not appear to be an object\"}\n" -"set value [$value self]}\n" +"set value [::xotcl::dispatch $value -objscope ::xotcl::self]}\n" "if {![::xotcl::is ${.elementtype} class]} {\n" "error \"$value does not appear to be of type ${.elementtype}\"}}\n" "set p [lsearch -exact $old $value]\n" @@ -225,8 +232,11 @@ "::xotcl::alias ::xotcl::InterceptorSlot set ::xotcl::relation ;# for backwards compatibility\n" "::xotcl::alias ::xotcl::InterceptorSlot assign ::xotcl::relation\n" "::xotcl::InterceptorSlot method add {obj -per-object:switch prop value {pos 0}} {\n" +"puts stderr interceptorslot-add-[self args]\n" "if {![set .multivalued]} {\n" "error \"Property $prop of ${.domain}->$obj ist not multivalued\"}\n" +"puts stderr \"BEFORE: $obj info $prop -guards => '[$obj info $prop -guards]'\"\n" +"puts stderr \"$obj $prop [linsert [$obj info $prop -guards] $pos $value]\"\n" "$obj $prop [linsert [$obj info $prop -guards] $pos $value]}\n" "proc ::xotcl::register_system_slots {os} {\n" "${os}::Object alloc ${os}::Class::slot\n" @@ -238,12 +248,7 @@ "::xotcl::InterceptorSlot create ${os}::Object::slot::mixin \\\n" "-type relation\n" "::xotcl::InterceptorSlot create ${os}::Object::slot::filter \\\n" -"-elementtype \"\" -type relation\n" -"::xotcl::InterceptorSlot create ${os}::Class::slot::instmixin \\\n" -"-type relation\n" -"::xotcl::InterceptorSlot create ${os}::Class::slot::instfilter \\\n" -"-elementtype \"\" \\\n" -"-type relation}\n" +"-elementtype \"\" -type relation}\n" "::xotcl::register_system_slots ::xotcl2\n" "::xotcl::MetaSlot invalidateobjectparameter\n" "::xotcl::MetaSlot create ::xotcl::Attribute -superclass ::xotcl::Slot\n" @@ -311,7 +316,7 @@ "if {[.procsearch assign] ne \"::xotcl::Slot instcmd assign\"} return\n" "if {[.procsearch get] ne \"::xotcl::Slot instcmd get\"} return\n" "${.domain} setter {*}[expr {${.per-object} ? \"-per-object\" : \"\"}] ${.name}}}\n" -"::xotcl::Attribute instmixin add ::xotcl::Slot::Optimizer\n" +"::xotcl::Attribute mixin add ::xotcl::Slot::Optimizer\n" "::xotcl2::Class create ::xotcl::ScopedNew -superclass ::xotcl2::Class\n" "createBootstrapAttributeSlots ::xotcl::ScopedNew {\n" "{withclass ::xotcl2::Object}\n" @@ -333,9 +338,10 @@ "if {$withnew} {\n" "set m [::xotcl::ScopedNew new \\\n" "-inobject $object -withclass $class -volatile]\n" -"::xotcl2::Class instmixin add $m end\n" +"::xotcl2::Class mixin add $m end\n" +"puts stderr \"after add $m: ::xotcl2::Class info mixin => [::xotcl2::Class info mixin]\"\n" "namespace eval $object $cmds\n" -"::xotcl2::Class instmixin delete $m} else {\n" +"::xotcl2::Class mixin delete $m} else {\n" "namespace eval $object $cmds}}\n" "::xotcl2::Class forward slots %self contains \\\n" "-object {%::xotcl::dispatch [::xotcl::self] -objscope ::subst [::xotcl::self]::slot}\n" Index: generic/predefined.xotcl =================================================================== diff -u -r8f79347327f3c5f73faf86e87ebd6c8306265fbb -rb708f296be8c5cbd3e4daa959713483dbdfdfd82 --- generic/predefined.xotcl (.../predefined.xotcl) (revision 8f79347327f3c5f73faf86e87ebd6c8306265fbb) +++ generic/predefined.xotcl (.../predefined.xotcl) (revision b708f296be8c5cbd3e4daa959713483dbdfdfd82) @@ -124,16 +124,19 @@ ::xotcl::alias ::xotcl2::classInfo [namespace tail $cmd] $cmd } foreach cmd [info command ::xotcl::cmd::ClassInfo::*] { - ::xotcl::alias ::xotcl2::classInfo [namespace tail $cmd] $cmd + set cmdName [namespace tail $cmd] + if {$cmdName in [list "instfilter" "instforward" "instmixin" "instparams"]} continue + ::xotcl::alias ::xotcl2::classInfo $cmdName $cmd } unset cmd #Object forward info -onerror ::xotcl::infoError ::xotcl2::objectInfo %1 {%@2 %self} #Class forward info -onerror ::xotcl::infoError ::xotcl2::classInfo %1 {%@2 %self} - Object forward info -onerror ::xotcl::infoError ::xotcl2::objectInfo %1 {%@2 %self} - Class forward info -onerror ::xotcl::infoError ::xotcl2::classInfo %1 {%@2 %self} - ::xotcl::dispatch ::xotcl2::classInfo ::xotcl::cmd::Object::forward "-per-object" ::xotcl2::objectInfo {%@2 %1} + Object forward info -onerror ::xotcl::infoError -verbose ::xotcl2::objectInfo %1 {%@2 %self} + Class forward info -onerror ::xotcl::infoError -verbose ::xotcl2::classInfo %1 {%@2 %self} + ::xotcl::dispatch ::xotcl2::classInfo ::xotcl::cmd::Object::forward \ + "-per-object" -verbose ::xotcl2::objectInfo {%@2 %1} proc ::xotcl::infoError msg { #puts stderr "INFO ERROR: <$msg>\n$::errorInfo" @@ -384,6 +387,7 @@ # since the domain object might be xotcl1 or 2, use dispatch ::xotcl::dispatch ${.domain} ::xotcl::cmd::Class::forward \ {*}[expr {${.per-object} ? "-per-object" : ""}] ${.name} \ + -verbose \ -default [${.manager} defaultmethods] ${.manager} %1 %self \ {*}[expr {[info exists .forward-per-object] ? "-per-object" : ""}] \ %proc @@ -401,13 +405,15 @@ ::xotcl::relation ::xotcl::InfoSlot superclass ::xotcl::Slot ::xotcl::InfoSlot method get {obj -per-object:switch prop} {$obj info $prop} ::xotcl::InfoSlot method add {obj -per-object:switch prop value {pos 0}} { + puts stderr infoslot-add-[self args] if {![set .multivalued]} { error "Property $prop of ${.domain}->$obj ist not multivalued" } puts stderr "adding infoslot: $obj $prop [linsert [$obj info $prop] $pos $value]" $obj $prop [linsert [$obj info $prop] $pos $value] } ::xotcl::InfoSlot method delete {-nocomplain:switch obj prop value} { + puts stderr infoslot-delete-[self args] set old [$obj info $prop] if {[string first * $value] > -1 || [string first \[ $value] > -1} { # string contains meta characters @@ -421,7 +427,7 @@ if {![::xotcl::is $value object]} { error "$value does not appear to be an object" } - set value [$value self] + set value [::xotcl::dispatch $value -objscope ::xotcl::self] } if {![::xotcl::is ${.elementtype} class]} { error "$value does not appear to be of type ${.elementtype}" @@ -445,9 +451,12 @@ ::xotcl::alias ::xotcl::InterceptorSlot assign ::xotcl::relation ::xotcl::InterceptorSlot method add {obj -per-object:switch prop value {pos 0}} { + puts stderr interceptorslot-add-[self args] if {![set .multivalued]} { error "Property $prop of ${.domain}->$obj ist not multivalued" } + puts stderr "BEFORE: $obj info $prop -guards => '[$obj info $prop -guards]'" + puts stderr "$obj $prop [linsert [$obj info $prop -guards] $pos $value]" $obj $prop [linsert [$obj info $prop -guards] $pos $value] } @@ -467,11 +476,11 @@ -type relation ::xotcl::InterceptorSlot create ${os}::Object::slot::filter \ -elementtype "" -type relation - ::xotcl::InterceptorSlot create ${os}::Class::slot::instmixin \ - -type relation - ::xotcl::InterceptorSlot create ${os}::Class::slot::instfilter \ - -elementtype "" \ - -type relation +# ::xotcl::InterceptorSlot create ${os}::Class::slot::object-mixin \ +# -type relation +# ::xotcl::InterceptorSlot create ${os}::Class::slot::instfilter \ +# -elementtype "" \ +# -type relation } ::xotcl::register_system_slots ::xotcl2 @@ -592,7 +601,7 @@ } } # register the optimizer per default -::xotcl::Attribute instmixin add ::xotcl::Slot::Optimizer +::xotcl::Attribute mixin add ::xotcl::Slot::Optimizer ################################################################## # Create a mixin class to overload method "new", such it does not allocate @@ -632,9 +641,10 @@ if {$withnew} { set m [::xotcl::ScopedNew new \ -inobject $object -withclass $class -volatile] - ::xotcl2::Class instmixin add $m end + ::xotcl2::Class mixin add $m end + puts stderr "after add $m: ::xotcl2::Class info mixin => [::xotcl2::Class info mixin]" namespace eval $object $cmds - ::xotcl2::Class instmixin delete $m + ::xotcl2::Class mixin delete $m } else { namespace eval $object $cmds } Index: generic/tclAPI.h =================================================================== diff -u -r8f79347327f3c5f73faf86e87ebd6c8306265fbb -rb708f296be8c5cbd3e4daa959713483dbdfdfd82 --- generic/tclAPI.h (.../tclAPI.h) (revision 8f79347327f3c5f73faf86e87ebd6c8306265fbb) +++ generic/tclAPI.h (.../tclAPI.h) (revision b708f296be8c5cbd3e4daa959713483dbdfdfd82) @@ -116,6 +116,7 @@ static int XOTclClassInfoInstpreMethodStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv []); static int XOTclClassInfoMethodMethodStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv []); static int XOTclClassInfoMethodsMethodStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv []); +static int XOTclClassInfoMixinMethodStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv []); static int XOTclClassInfoMixinofMethodStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv []); static int XOTclClassInfoParameterMethodStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv []); static int XOTclClassInfoSlotsMethodStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv []); @@ -212,6 +213,7 @@ static int XOTclClassInfoInstpreMethod(Tcl_Interp *interp, XOTclClass *class, char *methodName); static int XOTclClassInfoMethodMethod(Tcl_Interp *interp, XOTclClass *class, int infomethodsubcmd, char *name); static int XOTclClassInfoMethodsMethod(Tcl_Interp *interp, XOTclClass *object, int withDefined, int withMethodtype, int withNomixins, int withIncontext, char *pattern); +static int XOTclClassInfoMixinMethod(Tcl_Interp *interp, XOTclClass *class, int withClosure, int withGuards, char *patternString, XOTclObject *patternObj); static int XOTclClassInfoMixinofMethod(Tcl_Interp *interp, XOTclClass *class, int withClosure, char *patternString, XOTclObject *patternObj); static int XOTclClassInfoParameterMethod(Tcl_Interp *interp, XOTclClass *class); static int XOTclClassInfoSlotsMethod(Tcl_Interp *interp, XOTclClass *class); @@ -309,6 +311,7 @@ XOTclClassInfoInstpreMethodIdx, XOTclClassInfoMethodMethodIdx, XOTclClassInfoMethodsMethodIdx, + XOTclClassInfoMixinMethodIdx, XOTclClassInfoMixinofMethodIdx, XOTclClassInfoParameterMethodIdx, XOTclClassInfoSlotsMethodIdx, @@ -1002,6 +1005,41 @@ } static int +XOTclClassInfoMixinMethodStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { + parseContext pc; + + if (ArgumentParse(interp, objc, objv, NULL, objv[0], + method_definitions[XOTclClassInfoMixinMethodIdx].paramDefs, + method_definitions[XOTclClassInfoMixinMethodIdx].nrParameters, + &pc) != TCL_OK) { + return TCL_ERROR; + } else { + XOTclClass *class = (XOTclClass *)pc.clientData[0]; + int withClosure = (int )pc.clientData[1]; + int withGuards = (int )pc.clientData[2]; + char *patternString = NULL; + XOTclObject *patternObj = NULL; + Tcl_Obj *pattern = (Tcl_Obj *)pc.clientData[3]; + int returnCode; + + if (getMatchObject(interp, pattern, objv[3], &patternObj, &patternString) == -1) { + if (pattern) { + DECR_REF_COUNT(pattern); + } + return TCL_OK; + } + + parseContextRelease(&pc); + returnCode = XOTclClassInfoMixinMethod(interp, class, withClosure, withGuards, patternString, patternObj); + + if (pattern) { + DECR_REF_COUNT(pattern); + } + return returnCode; + } +} + +static int XOTclClassInfoMixinofMethodStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { parseContext pc; @@ -2405,6 +2443,12 @@ {"-incontext", 0, 0, convertToString}, {"pattern", 0, 0, convertToString}} }, +{"::xotcl::cmd::ClassInfo::mixin", XOTclClassInfoMixinMethodStub, 4, { + {"class", 1, 0, convertToClass}, + {"-closure", 0, 0, convertToString}, + {"-guards", 0, 0, convertToString}, + {"pattern", 0, 0, convertToObjpattern}} +}, {"::xotcl::cmd::ClassInfo::mixinof", XOTclClassInfoMixinofMethodStub, 3, { {"class", 1, 0, convertToClass}, {"-closure", 0, 0, convertToString}, Index: generic/xotcl.c =================================================================== diff -u -r8f79347327f3c5f73faf86e87ebd6c8306265fbb -rb708f296be8c5cbd3e4daa959713483dbdfdfd82 --- generic/xotcl.c (.../xotcl.c) (revision 8f79347327f3c5f73faf86e87ebd6c8306265fbb) +++ generic/xotcl.c (.../xotcl.c) (revision b708f296be8c5cbd3e4daa959713483dbdfdfd82) @@ -10921,9 +10921,9 @@ XOTclClassOpt *clopt = NULL, *nclopt = NULL; int i; - /*fprintf(stderr, "XOTclRelationCmd %s %d rel=%d val='%s'\n", + fprintf(stderr, "XOTclRelationCmd %s %d rel=%d val='%s'\n", objectName(object),withPer_object,relationtype,value?ObjStr(value):"NULL"); - */ + if (withPer_object) { switch (relationtype) { case RelationtypeClass_mixinIdx: @@ -10943,6 +10943,7 @@ XOTclObjectIsClass(object) ) { relationtype = RelationtypeClass_mixinIdx; + fprintf(stderr, "using class mixin\n"); } break; case RelationtypeObject_filterIdx: @@ -12543,6 +12544,9 @@ static int XOTclObjInfoMixinMethod(Tcl_Interp *interp, XOTclObject *object, int withGuards, int withOrder, char *patternString, XOTclObject *patternObj) { + + fprintf(stderr, "XOTclObjInfoMixinMethod'\n"); + if (withOrder) { if (!(object->flags & XOTCL_MIXIN_ORDER_VALID)) MixinComputeDefined(interp, object); @@ -12732,13 +12736,13 @@ return TCL_OK; } -static int XOTclClassInfoInstmixinMethod(Tcl_Interp *interp, XOTclClass * class, int withClosure, int withGuards, +static int XOTclClassInfoMixinMethod(Tcl_Interp *interp, XOTclClass * class, int withClosure, int withGuards, char *patternString, XOTclObject *patternObj) { XOTclClassOpt *opt = class->opt; int rc; - /*fprintf(stderr, "XOTclClassInfoInstmixinMethod guard %d clo %d set %.4x pattern '%s'\n", - withGuards,withClosure,patternString);*/ + fprintf(stderr, "XOTclClassInfoMixinMethod guard %d clo %d pattern '%s'\n", + withGuards,withClosure,patternString); if (withClosure) { Tcl_HashTable objTable, *commandTable = &objTable; @@ -12756,6 +12760,14 @@ return TCL_OK; } +/* TODO: this method should be removed, we should register XOTclClassInfoMixinMethod for + xotcl1 under name ... instmxin ... */ +static int XOTclClassInfoInstmixinMethod(Tcl_Interp *interp, XOTclClass * class, int withClosure, int withGuards, + char *patternString, XOTclObject *patternObj) { + return XOTclClassInfoMixinMethod(interp, class, withClosure, withGuards, patternString, patternObj); +} + + static int XOTclClassInfoInstmixinguardMethod(Tcl_Interp *interp, XOTclClass * class, char * mixin) { return class->opt ? GuardList(interp, class->opt->instmixins, mixin) : TCL_OK; } Index: library/lib/xotcl1.xotcl =================================================================== diff -u -r8f79347327f3c5f73faf86e87ebd6c8306265fbb -rb708f296be8c5cbd3e4daa959713483dbdfdfd82 --- library/lib/xotcl1.xotcl (.../xotcl1.xotcl) (revision 8f79347327f3c5f73faf86e87ebd6c8306265fbb) +++ library/lib/xotcl1.xotcl (.../xotcl1.xotcl) (revision b708f296be8c5cbd3e4daa959713483dbdfdfd82) @@ -305,7 +305,7 @@ } foreach cmd [::info command ::xotcl::cmd::ClassInfo::*] { set cmdName [namespace tail $cmd] - if {$cmdName in [list "method" "methods"]} continue + if {$cmdName in [list "method" "methods" "mixin"]} continue ::xotcl::alias ::xotcl::classInfo $cmdName $cmd } ::xotcl::alias ::xotcl::objectInfo is ::xotcl::is