Index: TODO =================================================================== diff -u -rb68d232ea609ee60060b451c02350dd210c11441 -rc95e8ce3d63c826e5d706b55acb3be94cb8edcde --- TODO (.../TODO) (revision b68d232ea609ee60060b451c02350dd210c11441) +++ TODO (.../TODO) (revision c95e8ce3d63c826e5d706b55acb3be94cb8edcde) @@ -2942,14 +2942,10 @@ unknown is a hook for Object but a method for Class - do we need contains in nx? -- are the oneline hook definitions like - Class protected class-object method __unknown {name} {} - needed? - nsf::proc * check, if there are parameter types that should not be applicable for nsf::proc - * scripted-method like implementation (like ProcMethodDispatch, not urgent) * toplevel (object less) introspection - "info method definition" for :attributes? @@ -2977,15 +2973,6 @@ package require nx::test namespace import ::nx::* - * parameter option allowempty is a little longish; we should - choose probably a shorter name - - Object create o { - :method foo {x:integer,allowempty y:integer os:object,multivalued,allowempty} { - return $x - } - } - - library + apps - new directory structure DONE - work on binary packages of xotcl (store + xml) Index: generic/nsf.c =================================================================== diff -u -rb68d232ea609ee60060b451c02350dd210c11441 -rc95e8ce3d63c826e5d706b55acb3be94cb8edcde --- generic/nsf.c (.../nsf.c) (revision b68d232ea609ee60060b451c02350dd210c11441) +++ generic/nsf.c (.../nsf.c) (revision c95e8ce3d63c826e5d706b55acb3be94cb8edcde) @@ -5970,6 +5970,21 @@ return rc; } +/* + *---------------------------------------------------------------------- + * RemoveFromClassMixinsOf -- + * + * Remove the class (provided as a cmd) from all isClassMixinOf definitions + * from the provided classes (provided as cmdlist). + * + * Results: + * void + * + * Side effects: + * Deletes potentially some entries in the isClassMixinOf lists. + * + *---------------------------------------------------------------------- + */ static void RemoveFromClassMixinsOf(Tcl_Command cmd, NsfCmdList *cmdlist) { @@ -5989,6 +6004,22 @@ } } +/* + *---------------------------------------------------------------------- + * RemoveFromObjectMixinsOf -- + * + * Remove the class (provided as a cmd) from all isObjectMixinOf definitions + * from the provided classes (provided as cmdlist). + * + * Results: + * void + * + * Side effects: + * Deletes potentially some entries in the isObjectMixinOf lists. + * + *---------------------------------------------------------------------- + */ + static void RemoveFromObjectMixinsOf(Tcl_Command cmd, NsfCmdList *cmdlist) { for ( ; cmdlist; cmdlist = cmdlist->nextPtr) { @@ -6006,6 +6037,22 @@ } } +/* + *---------------------------------------------------------------------- + * RemoveFromClassmixins -- + * + * Remove the class (provided as a cmd) from all classmixins lists + * from the provided classes (provided as cmdlist). + * + * Results: + * void + * + * Side effects: + * Deletes potentially some entries in the classmixins lists. + * + *---------------------------------------------------------------------- + */ + static void RemoveFromClassmixins(Tcl_Command cmd, NsfCmdList *cmdlist) { for ( ; cmdlist; cmdlist = cmdlist->nextPtr) { @@ -6024,8 +6071,23 @@ } } +/* + *---------------------------------------------------------------------- + * RemoveFromObjectMixins -- + * + * Remove the class (provided as a cmd) from all object mixin lists + * from the provided classes (provided as cmdlist). + * + * Results: + * void + * + * Side effects: + * Deletes potentially some entries in the objectmixins lists. + * + *---------------------------------------------------------------------- + */ static void -RemoveFromMixins(Tcl_Command cmd, NsfCmdList *cmdlist) { +RemoveFromObjectMixins(Tcl_Command cmd, NsfCmdList *cmdlist) { for ( ; cmdlist; cmdlist = cmdlist->nextPtr) { NsfObject *nobj = NsfGetObjectFromCmdPtr(cmdlist->cmdPtr); NsfObjectOpt *objopt = nobj ? nobj->opt : NULL; @@ -6044,7 +6106,19 @@ /* - * Reset mixin order for instances of a class + *---------------------------------------------------------------------- + * MixinResetOrderForInstances -- + * + * Reset the per-object mixin order for the instances of the provided + * class. + * + * Results: + * void + * + * Side effects: + * Deletes potentially the mixin list for the objects. + * + *---------------------------------------------------------------------- */ static void @@ -6070,7 +6144,21 @@ } } -/* reset mixin order for all objects having this class as per object mixin */ +/* + *---------------------------------------------------------------------- + * ResetOrderOfClassesUsedAsMixins -- + * + * Reset the per-object mixin order for all objects having this class as + * per-object mixin. + * + * Results: + * void + * + * Side effects: + * Deletes potentially the mixin list for the objects. + * + *---------------------------------------------------------------------- + */ static void ResetOrderOfClassesUsedAsMixins(NsfClass *cl) { /*fprintf(stderr, "ResetOrderOfClassesUsedAsMixins %s - %p\n", @@ -6088,12 +6176,24 @@ } } - - /* - * if the class hierarchy or class mixins have changed -> - * invalidate mixin entries in all dependent instances + *---------------------------------------------------------------------- + * MixinInvalidateObjOrders -- + * + * Reset mixin order for all instances of the class and the instances of + * its subclasses. This function is typically callled, when the the class + * hierarchy or the class mixins have changed and invalidate mixin entries + * in all dependent instances. + * + * Results: + * void + * + * Side effects: + * Deletes potentially the mixin list for the objects and classes. + * + *---------------------------------------------------------------------- */ + static void MixinInvalidateObjOrders(Tcl_Interp *interp, NsfClass *cl) { NsfClasses *saved = cl->order, *clPtr; @@ -6103,16 +6203,16 @@ cl->order = NULL; - /* reset mixin order for all instances of the class and the - instances of its subclasses - */ + /* + * Iterate over the subclass hierarchy. + */ for (clPtr = ComputeOrder(cl, cl->order, Sub); clPtr; clPtr = clPtr->nextPtr) { Tcl_HashSearch hSrch; - //Tcl_HashEntry *hPtr = &clPtr->cl->instances ? - //Tcl_FirstHashEntry(&clPtr->cl->instances, &hSrch) : NULL; Tcl_HashEntry *hPtr; - /* reset mixin order for all objects having this class as per object mixin */ + /* + * Reset mixin order for all objects having this class as per object mixin + */ ResetOrderOfClassesUsedAsMixins(clPtr->cl); /* fprintf(stderr, "invalidating instances of class %s\n", ClassName(clPtr)); @@ -6129,10 +6229,11 @@ NsfClassListFree(cl->order); cl->order = saved; - /* Reset mixin order for all objects having this class as a per - class mixin. This means that we have to work through - the class mixin hierarchy with its corresponding instances. - */ + /* + * Reset the mixin order for all objects having this class as a per class + * mixin. This means that we have to work through the class mixin hierarchy + * with its corresponding instances. + */ Tcl_InitHashTable(commandTable, TCL_ONE_WORD_KEYS); MEM_COUNT_ALLOC("Tcl_InitHashTable", commandTable); GetAllClassMixinsOf(interp, commandTable, Tcl_GetObjResult(interp), @@ -6144,7 +6245,10 @@ /*fprintf(stderr, "Got %s, reset for ncl %p\n", ncl?ClassName(ncl):"NULL", ncl);*/ if (ncl) { MixinResetOrderForInstances(ncl); - /* this place seems to be sufficient to invalidate the computed object parameter definitions */ + /* + * This place seems to be sufficient to invalidate the computed object + * parameter definitions. + */ /*fprintf(stderr, "MixinInvalidateObjOrders via class mixin %s calls ifd invalidate \n", ClassName(ncl));*/ NsfInvalidateObjectParameterCmd(interp, ncl); } @@ -6154,13 +6258,27 @@ } /* - * the mixin order is either - * DEFINED (there are mixins on the instance), - * NONE (there are no mixins for the instance), - * or INVALID (a class re-strucuturing has occured, thus it is not clear - * whether mixins are defined or not). - * If it is INVALID MixinComputeDefined can be used to compute the order - * and set the instance to DEFINED or NONE + *---------------------------------------------------------------------- + * MixinComputeDefined -- + * + * This function computes the mixin order for the provided object and + * adjusts the mixin flags accordingly. The mixin order is either + * + * DEFINED (there are mixins on the instance), + * NONE (there are no mixins for the instance), + * or INVALID (a class re-strucuturing has occured, + * thus it is not clear whether mixins are defined or not). + * + * If the mixin order is INVALID, MixinComputeDefined can be used to + * compute the order and set the instance to DEFINED or NONE + * + * Results: + * void + * + * Side effects: + * Might alter the mixin order. + * + *---------------------------------------------------------------------- */ static void MixinComputeDefined(Tcl_Interp *interp, NsfObject *object) { @@ -6173,7 +6291,6 @@ } } - /* *---------------------------------------------------------------------- * ComputePrecedenceList -- @@ -6193,7 +6310,8 @@ */ static NsfClasses * -ComputePrecedenceList(Tcl_Interp *interp, NsfObject *object, CONST char *pattern, +ComputePrecedenceList(Tcl_Interp *interp, NsfObject *object, + CONST char *pattern, int withMixins, int withRootClass) { NsfClasses *precedenceList = NULL, *pcl, **npl = &precedenceList; @@ -12258,7 +12376,7 @@ /* * Remove this class from all mixin lists and clear the isObjectMixinOf list */ - RemoveFromMixins(clopt->id, clopt->isObjectMixinOf); + RemoveFromObjectMixins(clopt->id, clopt->isObjectMixinOf); CmdListRemoveList(&clopt->isObjectMixinOf, GuardDel); /* Index: tests/parameters.test =================================================================== diff -u -r58c1880b874484f218afa0275b0998e25d4282f0 -rc95e8ce3d63c826e5d706b55acb3be94cb8edcde --- tests/parameters.test (.../parameters.test) (revision 58c1880b874484f218afa0275b0998e25d4282f0) +++ tests/parameters.test (.../parameters.test) (revision c95e8ce3d63c826e5d706b55acb3be94cb8edcde) @@ -1050,8 +1050,6 @@ ? {o foo "" 2 {o1 o2}} "" "first is empty" ? {o foo 1 "" {o1 o2}} {expected integer but got "" for parameter "y"} "second is empty" ? {o foo 1 2 {}} 1 "empty list" - # TODO allowempty change - #? {o foo 1 2 {o1 "" o2}} 1 "list contains empty value" ? {o info method parameter foo} "x:integer,0..1 y:integer os:object,0..*"