Index: TODO =================================================================== diff -u -r2249341e24800ec7e78438717dbef8524dbb14be -r5972bd087afec6d23d1192d552a29c92e570d8a6 --- TODO (.../TODO) (revision 2249341e24800ec7e78438717dbef8524dbb14be) +++ TODO (.../TODO) (revision 5972bd087afec6d23d1192d552a29c92e570d8a6) @@ -2776,7 +2776,19 @@ - added test cases for "info slots" +- nsf.c: + * handling of same named per-object and provided slots for Class objects + * per-object slots are saved now under ::per-object-slot::* + * returning correct results when per-object slots are used + * removed obsolete functions: NsfObjectListFree(), NsfObjectListAdd() + * removed obsolete type NsfObjects + * transformed ComputeSlotObjects() into a more generic AddSlotObjects() + that can handle per-object slots as well +- nx.tcl: + * generalized slot object handling. + * extended regression test + TODO: - handle same-named per-object and provided slots for Class objects Index: generic/nsf.c =================================================================== diff -u -r5bd1759237cbda063f4082f122330a39afd39387 -r5972bd087afec6d23d1192d552a29c92e570d8a6 --- generic/nsf.c (.../nsf.c) (revision 5bd1759237cbda063f4082f122330a39afd39387) +++ generic/nsf.c (.../nsf.c) (revision 5972bd087afec6d23d1192d552a29c92e570d8a6) @@ -1499,30 +1499,7 @@ } #endif -void -NsfObjectListFree(NsfObjects *sl) { - NsfObjects *n; - for (; sl; sl = n) { - n = sl->nextPtr; - FREE(NsfObjects, sl); - } -} -NsfObjects** -NsfObjectListAdd(NsfObjects **cList, NsfObject *object) { - NsfObjects *l = *cList, *element = NEW(NsfObjects); - element->obj = object; - element->nextPtr = NULL; - - if (l) { - while (l->nextPtr) l = l->nextPtr; - l->nextPtr = element; - } else - *cList = element; - return &(element->nextPtr); -} - - /* * precedence ordering functions */ @@ -10674,114 +10651,95 @@ /* *---------------------------------------------------------------------- - * ComputeSlotObjects -- + * AddSlotObjects -- * - * Compute the list of slots for a given precedence list (class list). + * Compute the slot objects (children of the slot container) for a provided + * object. The objects can be filtered via a pattern. * * Results: - * A list of NsfObjects or NULL + * The function appends results to the provide listObj * * Side effects: - * Returned List has to be freed by the caller + * Might add as well to the hash table to avoid duplicates * *---------------------------------------------------------------------- */ -static NsfObjects * -ComputeSlotObjects(Tcl_Interp *interp, NsfClasses *precedenceList, - int withSource, NsfClass *type, - CONST char *pattern) { - NsfObjects *slotObjects = NULL, **npl = &slotObjects; - Tcl_HashTable slotTable; - NsfClasses *clPtr; - int fullQualPattern = 0; +static void +AddSlotObjects(Tcl_Interp *interp, NsfObject *parent, CONST char *prefix, + Tcl_HashTable *slotTablePtr, + int withSource, NsfClass *type, CONST char *pattern, + Tcl_Obj *listObj) { + NsfObject *childObject, *slotContainerObject; + Tcl_DString ds, *dsPtr = &ds; + int fullQualPattern = (pattern && *pattern == ':'); - Tcl_InitHashTable(&slotTable, TCL_STRING_KEYS); - MEM_COUNT_ALLOC("Tcl_InitHashTable", slotTable); + /*fprintf(stderr, "AddSlotObjects parent %s prefix %s\n", ObjectName(parent), prefix);*/ - if (pattern && *pattern == ':') { - fullQualPattern = 1; - } + DSTRING_INIT(dsPtr); + Tcl_DStringAppend(dsPtr, ObjectName(parent), -1); + Tcl_DStringAppend(dsPtr, prefix, -1); + slotContainerObject = GetObjectFromString(interp, Tcl_DStringValue(dsPtr)); - for (clPtr = precedenceList; clPtr; clPtr = clPtr->nextPtr) { - Tcl_DString ds, *dsPtr = &ds; - NsfObject *childObject, *slotContainerObject; - - if (!MethodSourceMatches(withSource, clPtr->cl, NULL)) continue; + if (slotContainerObject && slotContainerObject->nsPtr) { + Tcl_HashSearch hSrch; + Tcl_HashEntry *hPtr; + Tcl_HashTable *cmdTablePtr = Tcl_Namespace_cmdTablePtr(slotContainerObject->nsPtr); + Tcl_Command cmd; + int new; - DSTRING_INIT(dsPtr); - Tcl_DStringAppend(dsPtr, ClassName(clPtr->cl), -1); - Tcl_DStringAppend(dsPtr, "::slot", 6); - slotContainerObject = GetObjectFromString(interp, Tcl_DStringValue(dsPtr)); - if (slotContainerObject) { - Tcl_HashSearch hSrch; - Tcl_HashEntry *hPtr; - Tcl_HashTable *cmdTablePtr; - Tcl_Command cmd; - int new; + hPtr = Tcl_FirstHashEntry(cmdTablePtr, &hSrch); + for (; hPtr; hPtr = Tcl_NextHashEntry(&hSrch)) { + char *key = Tcl_GetHashKey(cmdTablePtr, hPtr); - if (!slotContainerObject->nsPtr) continue; - cmdTablePtr = Tcl_Namespace_cmdTablePtr(slotContainerObject->nsPtr); + /* + * Check, if we have and entry with this key already processed. We + * never want to report shadowed entries. + */ + Tcl_CreateHashEntry(slotTablePtr, key, &new); + if (!new) continue; + + /* + * Obtain the childObject + */ + cmd = (Tcl_Command) Tcl_GetHashValue(hPtr); + childObject = NsfGetObjectFromCmdPtr(cmd); + if (!childObject) continue; - hPtr = Tcl_FirstHashEntry(cmdTablePtr, &hSrch); - for (; hPtr; hPtr = Tcl_NextHashEntry(&hSrch)) { - char *key = Tcl_GetHashKey(cmdTablePtr, hPtr); - + /* + * Check the pattern. + */ + if (pattern) { + int match; /* - * Check, if we have and entry with this key already processed. We - * never want to report shadowed entries. + * If the pattern looks like fully qualified, we match against the + * fully qualified name. */ - Tcl_CreateHashEntry(&slotTable, key, &new); - if (!new) continue; + match = fullQualPattern ? + Tcl_StringMatch(ObjectName(childObject), pattern) : + Tcl_StringMatch(key, pattern); - /* - * Obtain the childObject - */ - cmd = (Tcl_Command) Tcl_GetHashValue(hPtr); - childObject = NsfGetObjectFromCmdPtr(cmd); - - /* - * Check the pattern. - */ - if (pattern) { - int match; - /* - * If the pattern looks like fully qualified, we match against the - * fully qualified name. - */ - match = fullQualPattern ? - Tcl_StringMatch(ObjectName(childObject), pattern) : - Tcl_StringMatch(key, pattern); - - if (!match) { - continue; - } - } - - /* - * Check, if the entry is from the right type - */ - if (type && !IsSubType(childObject->cl, type)) { + if (!match) { continue; } - - /* - * Add finaly the entry to the returned list. - */ - npl = NsfObjectListAdd(npl, childObject); } + + /* + * Check, if the entry is from the right type + */ + if (type && !IsSubType(childObject->cl, type)) { + continue; + } + + /* + * Add finaly the entry to the returned list. + */ + Tcl_ListObjAppendElement(interp, listObj, childObject->cmdName); } - DSTRING_FREE(dsPtr); } - - Tcl_DeleteHashTable(&slotTable); - MEM_COUNT_FREE("Tcl_InitHashTable", slotTable); - - return slotObjects; + DSTRING_FREE(dsPtr); } - - static NsfClass * FindCalledClass(Tcl_Interp *interp, NsfObject *object) { NsfCallStackContent *cscPtr = CallStackGetTopFrame(interp, NULL); @@ -19242,22 +19200,40 @@ NsfObjInfoLookupSlotsMethod(Tcl_Interp *interp, NsfObject *object, int withSource, NsfClass *type, CONST char *pattern) { - NsfObjects *pl, *slotObjects; - Tcl_Obj *list = Tcl_NewListObj(0, NULL); - NsfClasses *fullPrecendenceList; + Tcl_Obj *listObj = Tcl_NewListObj(0, NULL); + NsfClasses *precendenceList, *clPtr; + Tcl_HashTable slotTable; - fullPrecendenceList = ComputePrecedenceList(interp, object, NULL /* pattern*/, 1, 1); + precendenceList = ComputePrecedenceList(interp, object, NULL /* pattern*/, 1, 1); if (withSource == 0) {withSource = 1;} - slotObjects = ComputeSlotObjects(interp, fullPrecendenceList, withSource, type, pattern); - for (pl=slotObjects; pl; pl = pl->nextPtr) { - Tcl_ListObjAppendElement(interp, list, pl->obj->cmdName); + Tcl_InitHashTable(&slotTable, TCL_STRING_KEYS); + MEM_COUNT_ALLOC("Tcl_InitHashTable", slotTable); + + /* + * First add the per-object slot objects + */ + if (1 && MethodSourceMatches(withSource, NULL, object)) { + AddSlotObjects(interp, object, "::per-object-slot", &slotTable, + withSource, type, pattern, listObj); } - NsfClassListFree(fullPrecendenceList); - NsfObjectListFree(slotObjects); + /* + * Then add the class provided slot objects + */ + for (clPtr = precendenceList; clPtr; clPtr = clPtr->nextPtr) { + if (MethodSourceMatches(withSource, clPtr->cl, NULL)) { + AddSlotObjects(interp, &clPtr->cl->object, "::slot", &slotTable, + withSource, type, pattern, listObj); + } + } - Tcl_SetObjResult(interp, list); + Tcl_DeleteHashTable(&slotTable); + MEM_COUNT_FREE("Tcl_InitHashTable", slotTable); + + NsfClassListFree(precendenceList); + Tcl_SetObjResult(interp, listObj); + return TCL_OK; } @@ -19799,44 +19775,60 @@ NsfClassInfoSlotsMethod(Tcl_Interp *interp, NsfClass *class, int withClosure, int withSource, NsfClass *type, CONST char *pattern) { - NsfClasses *clPtr, *intrinsic, *checkList = NULL, *mixinClasses = NULL, - *precedenceList = NULL; - Tcl_Obj *list = Tcl_NewListObj(0, NULL); - NsfObjects *pl, *slotObjects; + NsfClasses *clPtr, *intrinsic, *precedenceList = NULL; + Tcl_Obj *listObj = Tcl_NewListObj(0, NULL); + Tcl_HashTable slotTable; Tcl_ResetResult(interp); intrinsic = ComputeOrder(class, class->order, Super); if (withClosure) { + NsfClasses *checkList = NULL, *mixinClasses = NULL; + /* + * Compute the closure: first the transitive mixin classes... + */ NsfClassListAddPerClassMixins(interp, class, &mixinClasses, &checkList); for (clPtr = mixinClasses; clPtr; clPtr = clPtr->nextPtr) { if (NsfClassListFind(clPtr->nextPtr, clPtr->cl) == NULL && NsfClassListFind(intrinsic, clPtr->cl) == NULL) { NsfClassListAdd(&precedenceList, clPtr->cl, NULL); } } + /* + * ... followed by the intrinsic classes + */ NsfClassListAdd(&precedenceList, class, NULL); for (clPtr = intrinsic->nextPtr; clPtr; clPtr = clPtr->nextPtr) { NsfClassListAdd(&precedenceList, clPtr->cl, NULL); } + NsfClassListFree(checkList); + NsfClassListFree(mixinClasses); + } else { NsfClassListAdd(&precedenceList, class, NULL); } /* NsfClassListPrint("precedence", precedenceList);*/ if (withSource == 0) {withSource = 1;} - slotObjects = ComputeSlotObjects(interp, precedenceList, - withSource, type, pattern); - for (pl = slotObjects; pl; pl = pl->nextPtr) { - Tcl_ListObjAppendElement(interp, list, pl->obj->cmdName); + /* + * Use a hash table to eliminate potential duplicates. + */ + Tcl_InitHashTable(&slotTable, TCL_STRING_KEYS); + MEM_COUNT_ALLOC("Tcl_InitHashTable", slotTable); + + for (clPtr = precedenceList; clPtr; clPtr = clPtr->nextPtr) { + if (MethodSourceMatches(withSource, clPtr->cl, NULL)) { + AddSlotObjects(interp, &clPtr->cl->object, "::slot", &slotTable, + withSource, type, pattern, listObj); + } } + Tcl_DeleteHashTable(&slotTable); + MEM_COUNT_FREE("Tcl_InitHashTable", slotTable); + NsfClassListFree(precedenceList); - NsfClassListFree(mixinClasses); - NsfClassListFree(checkList); - NsfObjectListFree(slotObjects); + Tcl_SetObjResult(interp, listObj); - Tcl_SetObjResult(interp, list); return TCL_OK; } Index: generic/nsfInt.h =================================================================== diff -u -r5f856ff709f400d155ff730f532f646db5feef04 -r5972bd087afec6d23d1192d552a29c92e570d8a6 --- generic/nsfInt.h (.../nsfInt.h) (revision 5f856ff709f400d155ff730f532f646db5feef04) +++ generic/nsfInt.h (.../nsfInt.h) (revision 5972bd087afec6d23d1192d552a29c92e570d8a6) @@ -482,11 +482,6 @@ short activationCount; } NsfObject; -typedef struct NsfObjects { - struct NsfObject *obj; - struct NsfObjects *nextPtr; -} NsfObjects; - typedef struct NsfClassOpt { NsfCmdList *classfilters; NsfCmdList *classmixins; Index: library/nx/nx.tcl =================================================================== diff -u -r2249341e24800ec7e78438717dbef8524dbb14be -r5972bd087afec6d23d1192d552a29c92e570d8a6 --- library/nx/nx.tcl (.../nx.tcl) (revision 2249341e24800ec7e78438717dbef8524dbb14be) +++ library/nx/nx.tcl (.../nx.tcl) (revision 5972bd087afec6d23d1192d552a29c92e570d8a6) @@ -402,13 +402,14 @@ # # The function isSlotContainer tests, whether the provided object is # a slot container based on the methodproperty slotcontainer, used - # internally by nsf. + # internally by the serializer. # proc ::nx::isSlotContainer {object} { - if {[::nsf::object::exists $object] && [namespace tail $object] eq "slot"} { + set container [namespace tail $object] + if {[::nsf::object::exists $object] && $container in {slot per-object-slot}} { set parent [$object ::nsf::methods::object::info::parent] return [expr {[::nsf::object::exists $parent] - && [::nsf::method::property $parent -per-object slot slotcontainer]}] + && [::nsf::method::property $parent -per-object $container slotcontainer]}] } return 0 } @@ -419,20 +420,20 @@ # (when no slot name was provided) or the fully qualified name of # the slot object. # - proc ::nx::slotObj {baseObject {name ""}} { + nsf::proc ::nx::slotObj {{-container slot} baseObject name:optional} { # Create slot container object if needed - set slotContainer ${baseObject}::slot + set slotContainer ${baseObject}::$container if {![::nsf::object::exists $slotContainer]} { ::nx::Object ::nsf::methods::class::alloc $slotContainer - ::nsf::method::property ${baseObject} -per-object slot call-protected true - ::nsf::method::property ${baseObject} -per-object slot redefine-protected true - ::nsf::method::property ${baseObject} -per-object slot slotcontainer true + ::nsf::method::property ${baseObject} -per-object $container call-protected true + ::nsf::method::property ${baseObject} -per-object $container redefine-protected true + ::nsf::method::property ${baseObject} -per-object $container slotcontainer true $slotContainer ::nsf::methods::object::requirenamespace } - if {$name eq ""} { - return ${slotContainer} + if {[info exists name]} { + return ${slotContainer}::$name } - return ${slotContainer}::$name + return ${slotContainer} } # @@ -496,7 +497,7 @@ Object public method "delete attribute" {name} { # call explicitly the per-object variant of "info slots" - set slot [::nsf::my "::nx::Object::slot::__info::slots" $name] + set slot [::nsf::my ::nx::Object::slot::__info::slots $name] if {$slot eq ""} {error "[self]: cannot delete object specific attribute '$name'"} $slot destroy } @@ -547,7 +548,7 @@ :alias "info parent" ::nsf::methods::object::info::parent :alias "info precedence" ::nsf::methods::object::info::precedence :method "info slots" {{-type ::nx::Slot} pattern:optional} { - set slotContainer [::nsf::self]::slot + set slotContainer [::nsf::self]::per-object-slot if {[::nsf::object::exists $slotContainer]} { set cmd [list ::nsf::methods::object::info::children -type $type] if {[info exists pattern]} {lappend cmd $pattern} @@ -763,8 +764,10 @@ if {${per-object}} { lappend opts -per-object true set scope object + set container per-object-slot } else { set scope class + set container slot } if {$class eq ""} { @@ -773,8 +776,8 @@ #puts stderr "*** Class for '$value' is $class" } - #puts stderr "*** [list $class create [::nx::slotObj $target $name] {*}$opts $initblock]" - $class create [::nx::slotObj $target $name] {*}$opts $initblock + #puts stderr "*** [list $class create [::nx::slotObj -container $container $target $name] {*}$opts $initblock]" + $class create [::nx::slotObj -container $container $target $name] {*}$opts $initblock return [::nsf::dispatch $target ::nsf::methods::${scope}::info::method handle $name] } @@ -904,7 +907,7 @@ createBootstrapAttributeSlots ::nx::ObjectParameterSlot { {name "[namespace tail [::nsf::self]]"} - {domain "[lindex [regexp -inline {^(.*)::slot::[^:]+$} [::nsf::self]] 1]"} + {domain "[lindex [regexp -inline {^(.*)::(per-object-slot|slot)::[^:]+$} [::nsf::self]] 1]"} {manager "[::nsf::self]"} {per-object false} {methodname} @@ -963,6 +966,7 @@ if {[::nsf::is class ${:domain}]} { ::nsf::invalidateobjectparameter ${:domain} } + #puts stderr "*** slot destroy of [self], domain ${:domain} per-object ${:per-object}" # # delete the accessor # @@ -1644,7 +1648,7 @@ # itself foreach c $children { :makeTargetList $c - } + } } :method copyNSVarsAndCmds {orig dest} { @@ -1677,7 +1681,7 @@ # create obj set obj [[$origin info class] create $dest -noinit] } - # copy object -> may be a class obj + # copy object -> might be a class obj ::nsf::method::assertion $obj check [::nsf::method::assertion $origin check] ::nsf::method::assertion $obj object-invar [::nsf::method::assertion $origin object-invar] ::nsf::relation $obj object-filter [::nsf::relation $origin object-filter] @@ -1699,6 +1703,7 @@ ::nsf::method::forward $dest $i {*}[$origin ::nsf::methods::class::info::forward -definition $i] } } + set traces [list] foreach var [$origin info vars] { set cmds [::nsf::dispatch $origin -frame object ::trace info variable $var] @@ -1723,8 +1728,23 @@ # alter 'domain' and 'manager' in slot objects foreach origin [set :targetList] { set dest [:getDest $origin] - foreach oldslot [$origin info slots] { - set newslot [::nx::slotObj $dest [namespace tail $oldslot]] + set slots [list] + # + # get class specific slots + # + if {[::nsf::is class $origin]} { + set slots [$origin ::nx::Class::slot::__info::slots] + } + # + # append object specific slots + # + foreach slot [$origin ::nx::Object::slot::__info::slots] { + lappend slots $slot + } + #puts stderr "replacing domain and manager from <$origin> to <$dest> in slots <$slots>" + foreach oldslot $slots { + set container [expr {[$oldslot per-object] ? "per-object-slot" : "slot"}] + set newslot [::nx::slotObj -container $container $dest [namespace tail $oldslot]] if {[$oldslot domain] eq $origin} {$newslot domain $dest} if {[$oldslot manager] eq $oldslot} {$newslot manager $newslot} $newslot eval :init Index: library/serialize/serializer.tcl =================================================================== diff -u -rb04609014cf27559aa68b4d0d7ecb25288f993fc -r5972bd087afec6d23d1192d552a29c92e570d8a6 --- library/serialize/serializer.tcl (.../serializer.tcl) (revision b04609014cf27559aa68b4d0d7ecb25288f993fc) +++ library/serialize/serializer.tcl (.../serializer.tcl) (revision 5972bd087afec6d23d1192d552a29c92e570d8a6) @@ -216,7 +216,9 @@ set oss [set :serializer($c)] if {[$oss needsNothing $c [::nsf::current object]]} { lappend :level($stratum) $c - } + } else { + #puts stderr "$c needs something from $set" + } } if {[set :level($stratum)] eq ""} { set :level($stratum) $set @@ -706,9 +708,10 @@ :method Object-needsNothing {x s} { set p [$x info parent] + set cl [$x info class] if {$p ne "::" && [$s needsOneOf $p]} {return 0} - if {[$s needsOneOf [$x info class]]} {return 0} - if {[$s needsOneOf [$x ::nsf::methods::object::info::lookupslots]]} {return 0} + if {[$s needsOneOf $cl]} {return 0} + if {[$s needsOneOf [$cl ::nsf::methods::class::info::slots -closure -source application]]} {return 0} if {[$s needsOneOf [:alias-dependency $x object]]} {return 0} return 1 } Index: tests/info-method.test =================================================================== diff -u -r2249341e24800ec7e78438717dbef8524dbb14be -r5972bd087afec6d23d1192d552a29c92e570d8a6 --- tests/info-method.test (.../info-method.test) (revision 2249341e24800ec7e78438717dbef8524dbb14be) +++ tests/info-method.test (.../info-method.test) (revision 5972bd087afec6d23d1192d552a29c92e570d8a6) @@ -296,12 +296,13 @@ } ? {C info slots} "::C::slot::a ::C::slot::b" - ? {D class info slots} "::D::slot::a2" - ? {d1 info slots} "::d1::slot::a3" - # "a2" should not be included in the test cases below" - ? {D info slots} "::D::slot::b ::D::slot::a2 ::D::slot::c" - ? {d1 info lookup slots -source application} "::D::slot::b ::D::slot::a2 ::D::slot::c ::C::slot::a" - ? {D info slots -closure -source application} "::D::slot::b ::D::slot::a2 ::D::slot::c ::C::slot::a" + ? {D class info slots} "::D::per-object-slot::a2" + ? {d1 info slots} "::d1::per-object-slot::a3" + + ? {D info slots} "::D::slot::b ::D::slot::c" + + ? {d1 info lookup slots -source application} "::d1::per-object-slot::a3 ::D::slot::b ::D::slot::c ::C::slot::a" + ? {D info slots -closure -source application} "::D::slot::b ::D::slot::c ::C::slot::a" } # @@ -321,7 +322,7 @@ :method "sub foo" args {;} } - ? {D info lookup slots} "::nx::Class::slot::superclass ::nx::Class::slot::object-mixin ::nx::Class::slot::mixin ::nx::Class::slot::object-filter ::nx::Class::slot::filter ::nx::Class::slot::attributes ::nx::Object::slot::volatile ::nx::Object::slot::noinit ::nx::Object::slot::__initcmd ::nx::Object::slot::class" + ? {D info lookup slots} "::D::per-object-slot::a2 ::nx::Class::slot::superclass ::nx::Class::slot::object-mixin ::nx::Class::slot::mixin ::nx::Class::slot::object-filter ::nx::Class::slot::filter ::nx::Class::slot::attributes ::nx::Object::slot::volatile ::nx::Object::slot::noinit ::nx::Object::slot::__initcmd ::nx::Object::slot::class" C create c1 ? {c1 info precedence} "::C ::nx::Object" @@ -358,13 +359,13 @@ ? {c1 info lookup slots ::C::*} "::C::slot::a ::C::slot::b" D create d1 - ? {D info slots} "::D::slot::b ::D::slot::a2 ::D::slot::c" - ? {D info slots -closure -source application} "::D::slot::b ::D::slot::a2 ::D::slot::c ::C::slot::a" + ? {D info slots} "::D::slot::b ::D::slot::c" + ? {D info slots -closure -source application} "::D::slot::b ::D::slot::c ::C::slot::a" ? {::nx::Object info method parameter info} "" ? {d1 info precedence} "::D ::C ::nx::Object" - ? {d1 info lookup slots} "::D::slot::b ::D::slot::a2 ::D::slot::c ::C::slot::a ::nx::Object::slot::volatile ::nx::Object::slot::noinit ::nx::Object::slot::mixin ::nx::Object::slot::__initcmd ::nx::Object::slot::class ::nx::Object::slot::filter" + ? {d1 info lookup slots} "::D::slot::b ::D::slot::c ::C::slot::a ::nx::Object::slot::volatile ::nx::Object::slot::noinit ::nx::Object::slot::mixin ::nx::Object::slot::__initcmd ::nx::Object::slot::class ::nx::Object::slot::filter" # Fully qualified name, with metachars # The following command returns the slots of D inherited from @@ -503,8 +504,8 @@ ? {C info parameter spec b} "{-b 1}" ? {D info parameter spec b} "{-b 2}" - ? {D info parameter list} "-b -a2 -c -a -volatile -noinit -mixin -class -filter __initcmd" - ? {D info parameter name} "b a2 c a volatile noinit mixin class filter __initcmd" + ? {D info parameter list} "-b -c -a -volatile -noinit -mixin -class -filter __initcmd" + ? {D info parameter name} "b c a volatile noinit mixin class filter __initcmd" } # Index: tests/methods.test =================================================================== diff -u -r2ec475906a0ef436eebe94921b1a887c1a11d7cb -r5972bd087afec6d23d1192d552a29c92e570d8a6 --- tests/methods.test (.../methods.test) (revision 2ec475906a0ef436eebe94921b1a887c1a11d7cb) +++ tests/methods.test (.../methods.test) (revision 5972bd087afec6d23d1192d552a29c92e570d8a6) @@ -542,22 +542,21 @@ } ? {o1 info methods -path} "{info foo} {info bar foo} foo a1 a2" - ? {o1 info children} "::o1::info ::o1::slot" + ? {o1 info children} "::o1::info ::o1::per-object-slot" ? {o1 delete method bar} "::o1: cannot delete object specific method 'bar'" # For a1, we have a method and an attribute. We can delete the # method without the slot. ? {o1 delete method a1} "" # After the deletion of the accessor, the slot exists still - ? {o1::slot info children} "::o1::slot::a1 ::o1::slot::a2" - # If we perform now a "delete attribute", the slot will be removed. + ? {o1::per-object-slot info children} "::o1::per-object-slot::a1 ::o1::per-object-slot::a2" + # If we perform now a "delete attribute a1", the slot will be removed. ? {o1 delete attribute a1} "" - ? {o1::slot info children} "::o1::slot::a2" + ? {o1::per-object-slot info children} "::o1::per-object-slot::a2" # try to delete the attribute again: ? {o1 delete attribute a1} "::o1: cannot delete object specific attribute 'a1'" - ? {o1 info methods -path} "{info foo} {info bar foo} foo a2" ? {o1 delete attribute a2} "" ? {o1 info methods -path} "{info foo} {info bar foo} foo" @@ -585,10 +584,11 @@ :public class method foo {} {return [namespace current]-[namespace which info]} :public class method "info foo" {} {return [namespace current]-[namespace which info]} :public class method "info bar foo" {} {return [namespace current]-[namespace which info]} + :attribute a2 } ? {C class info methods -path} "{info foo} {info bar foo} foo a1" - ? {C info children} "::C::info ::C::slot" + ? {C info children} "::C::info ::C::slot ::C::per-object-slot" ? {C class delete method bar} "::C: cannot delete object specific method 'bar'" @@ -604,6 +604,9 @@ ? {C class delete method "info bar foo"} "" ? {C class info methods -path} "" + + ? {C info methods} "a2" + ? {C info slots} "::C::slot::a2" }