Index: generic/gentclAPI.decls =================================================================== diff -u -r08e94eff6214a9b51f96c9bd14dd521e89589b6e -r2880a345930ceabfec83d491f26b8254099c8991 --- generic/gentclAPI.decls (.../gentclAPI.decls) (revision 08e94eff6214a9b51f96c9bd14dd521e89589b6e) +++ generic/gentclAPI.decls (.../gentclAPI.decls) (revision 2880a345930ceabfec83d491f26b8254099c8991) @@ -48,12 +48,9 @@ {-argName "command" -required 1 -type tclobj} {-argName "args" -type args} } -xotclCmd dotdot XOTclDotDotCmd { +xotclCmd colon XOTclColonCmd { {-argName "args" -type allargs} } -xotclCmd dot XOTclDotCmd { - {-argName "args" -type allargs} -} xotclCmd exists XOTclExistsCmd { {-argName "object" -required 1 -type object} {-argName "var" -required 1} Index: generic/predefined.xotcl =================================================================== diff -u -rba41800193462bb1c6673f4774b56c9829cc991a -r2880a345930ceabfec83d491f26b8254099c8991 --- generic/predefined.xotcl (.../predefined.xotcl) (revision ba41800193462bb1c6673f4774b56c9829cc991a) +++ generic/predefined.xotcl (.../predefined.xotcl) (revision 2880a345930ceabfec83d491f26b8254099c8991) @@ -920,6 +920,7 @@ :method makeTargetList {t} { lappend :targetList $t + #puts stderr "COPY makeTargetList $t target= ${:targetList}" # if it is an object without namespace, it is a leaf if {[::xotcl::objectproperty $t object]} { if {[$t info hasnamespace]} { Index: generic/tclAPI.h =================================================================== diff -u -r08e94eff6214a9b51f96c9bd14dd521e89589b6e -r2880a345930ceabfec83d491f26b8254099c8991 --- generic/tclAPI.h (.../tclAPI.h) (revision 08e94eff6214a9b51f96c9bd14dd521e89589b6e) +++ generic/tclAPI.h (.../tclAPI.h) (revision 2880a345930ceabfec83d491f26b8254099c8991) @@ -190,12 +190,11 @@ static int XOTclOVwaitMethodStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv []); static int XOTclAliasCmdStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv []); static int XOTclAssertionCmdStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv []); +static int XOTclColonCmdStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv []); static int XOTclConfigureCmdStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv []); static int XOTclCreateObjectSystemCmdStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv []); static int XOTclDeprecatedCmdStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv []); static int XOTclDispatchCmdStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv []); -static int XOTclDotCmdStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv []); -static int XOTclDotDotCmdStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv []); static int XOTclExistsCmdStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv []); static int XOTclFinalizeObjCmdStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv []); static int XOTclForwardCmdStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv []); @@ -271,12 +270,11 @@ static int XOTclOVwaitMethod(Tcl_Interp *interp, XOTclObject *obj, char *varname); static int XOTclAliasCmd(Tcl_Interp *interp, XOTclObject *object, int withPer_object, char *methodName, int withNonleaf, int withObjscope, Tcl_Obj *cmdName); static int XOTclAssertionCmd(Tcl_Interp *interp, XOTclObject *object, int assertionsubcmd, Tcl_Obj *arg); +static int XOTclColonCmd(Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]); static int XOTclConfigureCmd(Tcl_Interp *interp, int configureoption, Tcl_Obj *value); static int XOTclCreateObjectSystemCmd(Tcl_Interp *interp, Tcl_Obj *rootClass, Tcl_Obj *rootMetaClass); static int XOTclDeprecatedCmd(Tcl_Interp *interp, char *what, char *oldCmd, char *newCmd); static int XOTclDispatchCmd(Tcl_Interp *interp, XOTclObject *object, int withObjscope, Tcl_Obj *command, int nobjc, Tcl_Obj *CONST nobjv[]); -static int XOTclDotCmd(Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]); -static int XOTclDotDotCmd(Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]); static int XOTclExistsCmd(Tcl_Interp *interp, XOTclObject *object, char *var); static int XOTclFinalizeObjCmd(Tcl_Interp *interp); static int XOTclForwardCmd(Tcl_Interp *interp, XOTclObject *object, int withPer_object, Tcl_Obj *method, Tcl_Obj *withDefault, int withEarlybinding, Tcl_Obj *withMethodprefix, int withObjscope, Tcl_Obj *withOnerror, int withVerbose, Tcl_Obj *target, int nobjc, Tcl_Obj *CONST nobjv[]); @@ -353,12 +351,11 @@ XOTclOVwaitMethodIdx, XOTclAliasCmdIdx, XOTclAssertionCmdIdx, + XOTclColonCmdIdx, XOTclConfigureCmdIdx, XOTclCreateObjectSystemCmdIdx, XOTclDeprecatedCmdIdx, XOTclDispatchCmdIdx, - XOTclDotCmdIdx, - XOTclDotDotCmdIdx, XOTclExistsCmdIdx, XOTclFinalizeObjCmdIdx, XOTclForwardCmdIdx, @@ -1498,6 +1495,15 @@ } static int +XOTclColonCmdStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { + + + + return XOTclColonCmd(interp, objc, objv); + +} + +static int XOTclConfigureCmdStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { parseContext pc; @@ -1576,24 +1582,6 @@ } static int -XOTclDotCmdStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { - - - - return XOTclDotCmd(interp, objc, objv); - -} - -static int -XOTclDotDotCmdStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { - - - - return XOTclDotDotCmd(interp, objc, objv); - -} - -static int XOTclExistsCmdStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { parseContext pc; @@ -2196,6 +2184,9 @@ {"assertionsubcmd", 1, 0, convertToAssertionsubcmd}, {"arg", 0, 0, convertToTclobj}} }, +{"::xotcl::colon", XOTclColonCmdStub, 1, { + {"args", 0, 0, convertToNothing}} +}, {"::xotcl::configure", XOTclConfigureCmdStub, 2, { {"configureoption", 1, 0, convertToConfigureoption}, {"value", 0, 0, convertToTclobj}} @@ -2215,12 +2206,6 @@ {"command", 1, 0, convertToTclobj}, {"args", 0, 0, convertToNothing}} }, -{"::xotcl::dot", XOTclDotCmdStub, 1, { - {"args", 0, 0, convertToNothing}} -}, -{"::xotcl::dotdot", XOTclDotDotCmdStub, 1, { - {"args", 0, 0, convertToNothing}} -}, {"::xotcl::exists", XOTclExistsCmdStub, 2, { {"object", 1, 0, convertToObject}, {"var", 1, 0, convertToString}} Index: generic/xotcl.c =================================================================== diff -u -r08e94eff6214a9b51f96c9bd14dd521e89589b6e -r2880a345930ceabfec83d491f26b8254099c8991 --- generic/xotcl.c (.../xotcl.c) (revision 08e94eff6214a9b51f96c9bd14dd521e89589b6e) +++ generic/xotcl.c (.../xotcl.c) (revision 2880a345930ceabfec83d491f26b8254099c8991) @@ -325,9 +325,6 @@ typedef Var * (Tcl_DeleteVarFunction) _ANSI_ARGS_ ( (Interp *iPtr, TclVarHashTable *tablePtr) ); -typedef Var * (lookupVarFromTableFunction) _ANSI_ARGS_ ( - (TclVarHashTable *varTable, CONST char *simpleName) - ); typedef struct TclVarHashTable85 { @@ -393,7 +390,6 @@ static Tcl_VarHashCreateVarFunction *tclVarHashCreateVar; static Tcl_InitVarHashTableFunction *tclInitVarHashTable; static Tcl_CleanupVarFunction *tclCleanupVar; -static lookupVarFromTableFunction *lookupVarFromTable; static int varRefCountOffset; static int varHashTableSize; @@ -578,19 +574,6 @@ } } } -static Var * -LookupVarFromTable84(TclVarHashTable *varTable, CONST char *simpleName) { - Var *varPtr = NULL; - Tcl_HashEntry *entryPtr; - - if (varTable) { - entryPtr = XOTcl_FindHashEntry(varTable, simpleName); - if (entryPtr) { - varPtr = VarHashGetValue(entryPtr); - } - } - return varPtr; -} #endif @@ -599,20 +582,17 @@ # define VarHashCreateVar (*tclVarHashCreateVar) # define InitVarHashTable (*tclInitVarHashTable) # define CleanupVar (*tclCleanupVar) -# define LookupVarFromTable (*lookupVarFromTable) # define TclCallFrame Tcl_CallFrame85 # else # define VarHashCreateVar VarHashCreateVar84 # define InitVarHashTable InitVarHashTable84 # define CleanupVar TclCleanupVar84 -# define LookupVarFromTable LookupVarFromTable84 # define TclCallFrame Tcl_CallFrame # endif #else # define VarHashCreateVar VarHashCreateVar85 # define InitVarHashTable TclInitVarHashTable # define CleanupVar TclCleanupVar -# define LookupVarFromTable LookupVarFromTable85 # define TclCallFrame Tcl_CallFrame #endif @@ -678,17 +658,6 @@ return varPtr; } -static XOTCLINLINE Var * -LookupVarFromTable85(TclVarHashTable *tablePtr, CONST char *simpleName) { - Var *varPtr = NULL; - if (tablePtr) { - Tcl_Obj *keyPtr = Tcl_NewStringObj(simpleName, -1); - Tcl_IncrRefCount(keyPtr); - varPtr = VarHashCreateVar85(tablePtr, keyPtr, NULL); - Tcl_DecrRefCount(keyPtr); - } - return varPtr; -} #endif @@ -1512,14 +1481,16 @@ * int flags, Tcl_Var *rPtr)); */ static int -NsDotVarResolver(Tcl_Interp *interp, CONST char *varName, Tcl_Namespace *nsPtr, int flags, Tcl_Var *varPtr) { +NsColonVarResolver(Tcl_Interp *interp, CONST char *varName, Tcl_Namespace *nsPtr, int flags, Tcl_Var *varPtr) { Tcl_CallFrame *varFramePtr; + TclVarHashTable *varTablePtr; + XOTclObject *object; int new, frameFlags; char firstChar, secondChar; Tcl_Obj *key; Var *newVar; - /*fprintf(stderr, "varResolver '%s' flags %.6x\n", varName, flags);*/ + /*fprintf(stderr, "NsColonVarResolver '%s' flags %.6x\n", varName, flags);*/ /* Case 1: The variable is to be resolved in global scope, proceed in * resolver chain (i.e. return TCL_CONTINUE) @@ -1539,7 +1510,7 @@ frameFlags = Tcl_CallFrame_isProcCallFrame(varFramePtr); #if defined (VAR_RESOLVER_TRACE) - fprintf(stderr, "NsDotVarResolver '%s' frame flags %.6x\n", varName, + fprintf(stderr, "NsColonVarResolver '%s' frame flags %.6x\n", varName, Tcl_CallFrame_isProcCallFrame(varFramePtr)); #endif @@ -1551,61 +1522,77 @@ name, varFramePtr, Tcl_CallFrame_isProcCallFrame(varFramePtr));*/ return TCL_CONTINUE; } - + firstChar = *varName; secondChar = *(varName+1); - if ((frameFlags & (FRAME_IS_XOTCL_CMETHOD|FRAME_IS_XOTCL_OBJECT)) && -#if USE_DOT - firstChar == '.' -#endif -#if USE_COLON - firstChar == ':' && secondChar != ':' -#endif - ) { - /* - * Case 3: we are in an XOTcl frame and the variable name starts with a "." - * We skip the dot, but stay in the resolver. - */ - varName ++; - } else if ((firstChar == ':' && secondChar == ':') || NSTail(varName) != varName) { + if (frameFlags & (FRAME_IS_XOTCL_CMETHOD|FRAME_IS_XOTCL_OBJECT)) { + /* + Case 3: we are in an XOTcl frame + */ + if (firstChar == ':') { + if (secondChar != ':') { + /* + * Case 3a: The variable name starts with a single ":". Skip + * the char, but stay in the resolver. + */ + varName ++; + } else { + /* + Case 3b: Names starting with "::" are not for us + */ + return TCL_CONTINUE; + } + } else if (NSTail(varName) != varName) { + /* + Case 3c: Names containing "::" are not for us + */ + return TCL_CONTINUE; + } + object = (frameFlags & FRAME_IS_XOTCL_CMETHOD) + ? ((XOTclCallStackContent *)Tcl_CallFrame_clientData(varFramePtr))->self + : (XOTclObject *)Tcl_CallFrame_clientData(varFramePtr); + + } else { /* - * Case 4: Check for absolutely/relatively qualified variable names, - * i.e. make sure that the variable name does not contain any - * namespace qualifiers. Proceed with a TCL_CONTINUE, otherwise. + * Case 4: we are not in an XOTcl frame, so proceed with a + * TCL_CONTINUE. */ return TCL_CONTINUE; + } + + /* We have an object and create the variable if not found */ + assert(object); + + varTablePtr = object->nsPtr ? Tcl_Namespace_varTable(object->nsPtr) : object->varTable; + if (varTablePtr == NULL && object->varTable == NULL) { + fprintf(stderr, "+++ create varTable in InterpColonVarResolver\n"); + varTablePtr = object->varTable = VarHashTableCreate(); } /* - * Does the variable exist in the per-object namespace? + * Does the variable exist in the object's namespace? */ - *varPtr = (Tcl_Var)LookupVarFromTable(Tcl_Namespace_varTable(nsPtr), varName); + + key = Tcl_NewStringObj(varName, -1); + INCR_REF_COUNT(key); + + *varPtr = (Tcl_Var)VarHashCreateVar(varTablePtr, key, NULL); + +#if defined (VAR_RESOLVER_TRACE) + fprintf(stderr, "...... lookup of '%s' for object '%s' returns %p\n", + varName, objectName(object), *varPtr); +#endif if (*varPtr == NULL) { - /* We failed to find the variable so far, therefore we create it - * in this namespace. Note that the cases (1), (2) and (4) - * TCL_CONTINUE care for variable creation if necessary. + /* + * We failed to find the variable so far, therefore we create it + * in this var table. Note that in several cases above, + * TCL_CONTINUE takes care for variable creation. */ - if ( -#if USE_DOT - firstChar != '.' -#endif -#if USE_COLON - firstChar != ':' -#endif - && (frameFlags & FRAME_IS_XOTCL_CMETHOD)) { - fprintf(stderr, ".... refuse to create var %s\n", varName); - return TCL_CONTINUE; - } + newVar = VarHashCreateVar(varTablePtr, key, &new); - key = Tcl_NewStringObj(varName, -1); - - INCR_REF_COUNT(key); - newVar = VarHashCreateVar(Tcl_Namespace_varTable(nsPtr), key, &new); - DECR_REF_COUNT(key); - #if defined(PRE85) # if FORWARD_COMPATIBLE if (!forwardCompatibleMode) { @@ -1615,21 +1602,12 @@ newVar->nsPtr = (Namespace *)ns; # endif #endif + DECR_REF_COUNT(key); *varPtr = (Tcl_Var)newVar; } return *varPtr ? TCL_OK : TCL_ERROR; } -#if 0 -static int -NsDotCmdResolver(Tcl_Interp *interp, CONST char *cmdName, Tcl_Namespace *nsPtr, int flags, Tcl_Command *cmdPtr) { - - fprintf(stderr, "NsDotCmdResolver cmdName %s flags %.6x\n",cmdName,flags); - return TCL_CONTINUE; -} -#endif - - #if defined(USE_COMPILED_VAR_RESOLVER) typedef struct xotclResolvedVarInfo { Tcl_ResolvedVarInfo vInfo; /* This must be the first element. */ @@ -1651,7 +1629,7 @@ } static Tcl_Var -CompiledDotVarFetch(Tcl_Interp *interp, Tcl_ResolvedVarInfo *vinfoPtr) { +CompiledColonVarFetch(Tcl_Interp *interp, Tcl_ResolvedVarInfo *vinfoPtr) { xotclResolvedVarInfo *resVarInfo = (xotclResolvedVarInfo *)vinfoPtr; XOTclCallStackContent *cscPtr = CallStackGetFrame(interp, NULL); XOTclObject *object = cscPtr ? cscPtr->self : NULL; @@ -1660,7 +1638,7 @@ int new, flags = var ? ((Var*)var)->flags : 0; #if defined(VAR_RESOLVER_TRACE) - fprintf(stderr,"CompiledDotVarFetch var '%s' var %p flags = %.4x dead? %.4x\n", + fprintf(stderr,"CompiledColonVarFetch var '%s' var %p flags = %.4x dead? %.4x\n", ObjStr(resVarInfo->nameObj), var, flags, flags&VAR_DEAD_HASH); #endif @@ -1694,7 +1672,7 @@ * initialize the variable hash table and update the object */ varTablePtr = object->varTable = VarHashTableCreate(); - fprintf(stderr, "+++ create varTable in %s CompiledDotVarFetch for '%s'\n", + fprintf(stderr, "+++ create varTable in %s CompiledColonVarFetch for '%s'\n", objectName(object), ObjStr(resVarInfo->nameObj)); } @@ -1718,21 +1696,16 @@ return var; } -void CompiledDotVarFree(Tcl_ResolvedVarInfo *vinfoPtr) { +void CompiledColonVarFree(Tcl_ResolvedVarInfo *vinfoPtr) { xotclResolvedVarInfo *resVarInfo = (xotclResolvedVarInfo *)vinfoPtr; DECR_REF_COUNT(resVarInfo->nameObj); if (resVarInfo->var) {HashVarFree(resVarInfo->var);} ckfree((char *) vinfoPtr); } -#if USE_DOT -#define FOR_RESOLVER(ptr) (*(ptr) == '.') -#endif -#if USE_COLON -#define FOR_RESOLVER(ptr) (*(ptr) == ':' && *(ptr+1) != ':') -#endif +#define FOR_COLON_RESOLVER(ptr) (*(ptr) == ':' && *(ptr+1) != ':') -int InterpCompiledDotVarResolver(Tcl_Interp *interp, +int InterpCompiledColonVarResolver(Tcl_Interp *interp, CONST84 char *name, int length, Tcl_Namespace *context, Tcl_ResolvedVarInfo **rPtr) { /* getting the self object is a weak protection against handling of wrong vars */ @@ -1741,11 +1714,11 @@ fprintf(stderr, "compiled var resolver for %s, obj %p\n", name, object); #endif - if (object && FOR_RESOLVER(name)) { + if (object && FOR_COLON_RESOLVER(name)) { xotclResolvedVarInfo *vInfoPtr = (xotclResolvedVarInfo *) ckalloc(sizeof(xotclResolvedVarInfo)); - vInfoPtr->vInfo.fetchProc = CompiledDotVarFetch; - vInfoPtr->vInfo.deleteProc = CompiledDotVarFree; /* if NULL, tcl does a ckfree on proc clean up */ + vInfoPtr->vInfo.fetchProc = CompiledColonVarFetch; + vInfoPtr->vInfo.deleteProc = CompiledColonVarFree; /* if NULL, tcl does a ckfree on proc clean up */ vInfoPtr->lastObj = NULL; vInfoPtr->var = NULL; memcpy(vInfoPtr->buffer, name+1, length-1); @@ -1760,11 +1733,11 @@ } static int -InterpDotCmdResolver(Tcl_Interp *interp, CONST char *cmdName, Tcl_Namespace *nsPtr, int flags, Tcl_Command *cmdPtr) { +InterpColonCmdResolver(Tcl_Interp *interp, CONST char *cmdName, Tcl_Namespace *nsPtr, int flags, Tcl_Command *cmdPtr) { CallFrame *varFramePtr; int frameFlags; - if (!FOR_RESOLVER(cmdName) || flags & TCL_GLOBAL_ONLY) { + if (!FOR_COLON_RESOLVER(cmdName) || flags & TCL_GLOBAL_ONLY) { /* ordinary names and global lookups are not for us */ return TCL_CONTINUE; } @@ -1776,70 +1749,60 @@ if (frameFlags == 0 && Tcl_CallFrame_callerPtr(varFramePtr)) { varFramePtr = (CallFrame *)Tcl_CallFrame_callerPtr(varFramePtr); frameFlags = Tcl_CallFrame_isProcCallFrame(varFramePtr); -#if defined(DOT_CMD_RESOLVER_TRACE) - fprintf(stderr, "InterpDotCmdResolver uses parent frame\n"); +#if defined(CMD_RESOLVER_TRACE) + fprintf(stderr, "InterpColonCmdResolver uses parent frame\n"); #endif } -#if defined(DOT_CMD_RESOLVER_TRACE) - fprintf(stderr, "InterpDotCmdResolver cmdName %s flags %.6x, frame flags %.6x\n",cmdName, +#if defined(CMD_RESOLVER_TRACE) + fprintf(stderr, "InterpColonCmdResolver cmdName %s flags %.6x, frame flags %.6x\n",cmdName, flags, Tcl_CallFrame_isProcCallFrame(varFramePtr)); #endif if (frameFlags & (FRAME_IS_XOTCL_METHOD|FRAME_IS_XOTCL_OBJECT|FRAME_IS_XOTCL_CMETHOD )) { -#if defined(DOT_CMD_RESOLVER_TRACE) - fprintf(stderr, " ... call dotCmd for %s\n", cmdName); +#if defined(CMD_RESOLVER_TRACE) + fprintf(stderr, " ... call colonCmd for %s\n", cmdName); #endif - if (*(cmdName+1) == '.') { - /* the command name starts with ".." */ - Tcl_Command cmd = Tcl_FindCommand(interp, cmdName+1, NULL, TCL_GLOBAL_ONLY); - if (cmd) { - fprintf(stderr, " we found a CMD for %s\n", cmdName+1); - *cmdPtr = RUNTIME_STATE(interp)->dotDotCmd; - return TCL_OK; - } else { - fprintf(stderr, " we found NO CMD for %s\n", cmdName+1); - } - } /* - * We have a cmd starting with ".", we are in an xotcl frame, so - * forward to the dotCmd. + * We have a cmd starting with ':', we are in an xotcl frame, so + * forward to the colonCmd. */ - *cmdPtr = RUNTIME_STATE(interp)->dotCmd; + *cmdPtr = RUNTIME_STATE(interp)->colonCmd; return TCL_OK; } -#if defined(DOT_CMD_RESOLVER_TRACE) +#if defined(CMD_RESOLVER_TRACE) fprintf(stderr, " ... not found %s\n", cmdName); tcl85showStack(interp); #endif return TCL_CONTINUE; } static int -InterpDotVarResolver(Tcl_Interp *interp, CONST char *varName, Tcl_Namespace *nsPtr, int flags, Tcl_Var *varPtr) { +InterpColonVarResolver(Tcl_Interp *interp, CONST char *varName, Tcl_Namespace *nsPtr, int flags, Tcl_Var *varPtr) { int new, frameFlags; CallFrame *varFramePtr; TclVarHashTable *varTablePtr; XOTclObject *object; + Tcl_Obj *keyObj; Tcl_Var var; - /*fprintf(stderr, "InterpDotVarResolver '%s' flags %.6x\n", varName, flags);*/ + /*fprintf(stderr, "InterpColonVarResolver '%s' flags %.6x\n", varName, flags);*/ - if (!FOR_RESOLVER(varName) || flags & TCL_GLOBAL_ONLY) { + if (!FOR_COLON_RESOLVER(varName) || flags & TCL_GLOBAL_ONLY) { /* ordinary names and global lookups are not for us */ return TCL_CONTINUE; } #if defined(VAR_RESOLVER_TRACE) - fprintf(stderr, "InterpDotVarResolver called var '%s' flags %.4x\n", varName, flags); + fprintf(stderr, "InterpColonVarResolver called var '%s' flags %.4x\n", varName, flags); #endif varName ++; varFramePtr = Tcl_Interp_varFramePtr(interp); frameFlags = Tcl_CallFrame_isProcCallFrame(varFramePtr); #if 0 - /* This chunk is needed in the dotcmd resolver, but does not seem to + /* This chunk is needed in the colonCmd resolver, but does not seem to be required here */ if (frameFlags == 0 && Tcl_CallFrame_callerPtr(varFramePtr)) { varFramePtr = (CallFrame *)Tcl_CallFrame_callerPtr(varFramePtr); @@ -1880,29 +1843,33 @@ varTablePtr = object->nsPtr ? Tcl_Namespace_varTable(object->nsPtr) : object->varTable; if (varTablePtr == NULL && object->varTable == NULL) { - fprintf(stderr, "+++ create varTable in InterpDotVarResolver\n"); + fprintf(stderr, "+++ create varTable in InterpColonVarResolver\n"); varTablePtr = object->varTable = VarHashTableCreate(); } - + /*fprintf(stderr, "Object Var Resolver, name=%s, obj %p, nsPtr %p, varTable %p\n", varName, obj, obj->nsPtr, varTablePtr);*/ - var = (Tcl_Var)LookupVarFromTable(varTablePtr, varName); + + keyObj = Tcl_NewStringObj(varName, -1); + INCR_REF_COUNT(keyObj); + + var = (Tcl_Var)VarHashCreateVar(varTablePtr, keyObj, NULL); if (var) { #if defined(VAR_RESOLVER_TRACE) fprintf(stderr, ".... found in hashtable %s %p\n", varName, var); #endif } else { - /* We failed to find the variable, therefore we create it new */ - Tcl_Obj *key = Tcl_NewStringObj(varName, -1); - - INCR_REF_COUNT(key); - var = (Tcl_Var)VarHashCreateVar(varTablePtr, key, &new); - DECR_REF_COUNT(key); + /* + We failed to find the variable, therefore we create it new + */ + var = (Tcl_Var)VarHashCreateVar(varTablePtr, keyObj, &new); #if defined(VAR_RESOLVER_TRACE) - fprintf(stderr, ".... created in hashtable %s %p\n", varName, var); + fprintf(stderr, ".... var %p %s created in hashtable %p\n", var, varName, varTablePtr); #endif } *varPtr = var; + DECR_REF_COUNT(keyObj); + return TCL_OK; } @@ -1916,9 +1883,9 @@ * acquiring the namespace. Works for object-scoped commands/procs * and object-only ones (set, unset, ...) */ - Tcl_SetNamespaceResolvers(object->nsPtr, /*(Tcl_ResolveCmdProc*)NsDotCmdResolver*/ NULL, - NsDotVarResolver, - /*(Tcl_ResolveCompiledVarProc*)NsCompiledDotVarResolver*/NULL); + Tcl_SetNamespaceResolvers(object->nsPtr, /*(Tcl_ResolveCmdProc*)NsColonCmdResolver*/ NULL, + NsColonVarResolver, + /*(Tcl_ResolveCompiledVarProc*)NsCompiledColonVarResolver*/NULL); return object->nsPtr; } @@ -5875,7 +5842,7 @@ methodName = ObjStr(methodObj); #if defined(USE_COMPILED_VAR_RESOLVER) - if (FOR_RESOLVER(methodName)) { + if (FOR_COLON_RESOLVER(methodName)) { methodName ++; } #endif @@ -8931,7 +8898,7 @@ /* if we dispatch a method via ".", we do not want to see the "." in the %proc, e.g. for the interceptor slots (such as .mixin, ... */ - if (FOR_RESOLVER(methodName)) { + if (FOR_COLON_RESOLVER(methodName)) { *out = Tcl_NewStringObj(methodName + 1, -1); } else { *out = objv[0]; @@ -9410,7 +9377,7 @@ if (Tcl_ListObjGetElements(interp, obj, objc, objv) == TCL_OK && *objc>1) { flag = ObjStr(*objv[0]); /*fprintf(stderr, "we have a list starting with '%s'\n", flag);*/ - if (*flag == '-' || *flag == '.') { /* TODO '.' needed? */ + if (*flag == '-') { *methodName = flag+1; return LIST_DASH; } @@ -10550,7 +10517,13 @@ for (; hPtr; hPtr = Tcl_NextHashEntry(&hSrch)) { key = Tcl_GetHashKey(cmdTable, hPtr); if (!pattern || Tcl_StringMatch(key, pattern)) { - if ((childObject = XOTclpGetObject(interp, key)) && + Tcl_Command cmd = (Tcl_Command)Tcl_GetHashValue(hPtr); + + /*fprintf(stderr, "... check %s child key %s child object %p %p\n", + objectName(object),key,XOTclpGetObject(interp, key), + XOTclGetObjectFromCmdPtr(cmd));*/ + + if ((childObject = XOTclGetObjectFromCmdPtr(cmd)) && (!classesOnly || XOTclObjectIsClass(childObject)) && (Tcl_Command_nsPtr(childObject->id) == object->nsPtr) /* true children */ ) { @@ -11194,51 +11167,22 @@ } /* -xotclCmd dot XOTclDotCmd { +xotclCmd colon XOTclColonCmd { {-argName "args" -type allargs} } */ -static int XOTclDotCmd(Tcl_Interp *interp, int nobjc, Tcl_Obj *CONST nobjv[]) { +static int XOTclColonCmd(Tcl_Interp *interp, int nobjc, Tcl_Obj *CONST nobjv[]) { XOTclObject *self = GetSelfObj(interp); if (!self) { return XOTclVarErrMsg(interp, "Cannot resolve 'self', probably called outside the context of an XOTcl Object", (char *) NULL); } - /*fprintf(stderr, "Dot dispatch %s on %s\n", ObjStr(nobjv[0]), objectName(self));*/ + /*fprintf(stderr, "Colon dispatch %s on %s\n", ObjStr(nobjv[0]), objectName(self));*/ return ObjectDispatch(self, interp, nobjc, nobjv, XOTCL_CM_NO_SHIFT); } /* -xotclCmd dotdot XOTclDotDotCmd { - {-argName "args" -type allargs} -} -*/ -static int XOTclDotDotCmd(Tcl_Interp *interp, int nobjc, Tcl_Obj *CONST nobjv[]) { - char *methodName = ObjStr(nobjv[0]); - - /* We want to call a command with bypassing the command resolver, - since the the command resolver will call InterpDotCmdResolver - again. Therefore we perform a single lookup and call the cmd - directly - */ - fprintf(stderr, "DotDot dispatch %s\n", methodName); - if (*(methodName+1) == '.') { - Tcl_Command cmd = Tcl_FindCommand(interp, methodName+1, NULL, TCL_GLOBAL_ONLY); - if (cmd) { - fprintf(stderr, " ... calling DotDot on %s cmd %p\n", methodName+1, cmd); - return Tcl_NRCallObjProc(interp, Tcl_Command_objProc(cmd), - Tcl_Command_objClientData(cmd), - nobjc, nobjv); - } - } - - return XOTclVarErrMsg(interp, "unknown command name '", - methodName+1, "'", (char *) NULL); -} - - -/* xotclCmd exists XOTclExistsCmd { {-argName "object" -required 1 -type object} {-argName "var" -required 1} @@ -13065,33 +13009,6 @@ int i, start = 1, argc, nextArgc, normalArgs, result = TCL_OK, isdasharg = NO_DASH; char *methodName, *nextMethodName; -#if 0 - /* if we got a single argument, try to split it (unless it starts - * with our magic chars) to distinguish between - * Object create foo {.method foo {} {...}} - * and - * Object create foo { - * {.method foo {} {...}} - * } - */ - if (objc == 2) { - Tcl_Obj **ov; - char *word = ObjStr(objv[1]); - if (*word != '.' && *word != '-') { /* TODO '.' needed */ - char *p = word; - while (*p && *p != ' ') p++; - if (*p) { - /*fprintf(stderr, "split %s\n", word);*/ - if (Tcl_ListObjGetElements(interp, objv[1], &objc, &ov) == TCL_OK) { - objv = (Tcl_Obj *CONST*)ov; - start = 0; - } else { - return TCL_ERROR; - } - } - } - } -#endif /* find arguments without leading dash */ for (i=start; i < objc; i++) { if ((isdasharg = isDashArg(interp, objv[i], 1, &methodName, &argc, &argv))) { @@ -14586,7 +14503,6 @@ fprintf(stderr, "loading a version of xotcl compiled for 8.4 version into a 8.4 Tcl\n"); */ forwardCompatibleMode = 0; - lookupVarFromTable = LookupVarFromTable84; tclVarHashCreateVar = VarHashCreateVar84; tclInitVarHashTable = InitVarHashTable84; tclCleanupVar = TclCleanupVar84; @@ -14601,7 +14517,6 @@ fprintf(stderr, "loading a version of xotcl compiled for 8.4 version into a 8.5 Tcl\n"); */ forwardCompatibleMode = 1; - lookupVarFromTable = LookupVarFromTable85; tclVarHashCreateVar = VarHashCreateVar85; tclInitVarHashTable = (Tcl_InitVarHashTableFunction*)*((&tclIntStubsPtr->reserved0)+235); tclCleanupVar = (Tcl_CleanupVarFunction*)*((&tclIntStubsPtr->reserved0)+176); @@ -14729,11 +14644,10 @@ #if defined(USE_COMPILED_VAR_RESOLVER) Tcl_AddInterpResolvers(interp,"xotcl", - (Tcl_ResolveCmdProc*)InterpDotCmdResolver, - InterpDotVarResolver, - (Tcl_ResolveCompiledVarProc*)InterpCompiledDotVarResolver); - RUNTIME_STATE(interp)->dotCmd = Tcl_FindCommand(interp, "::xotcl::dot", 0, 0); - RUNTIME_STATE(interp)->dotDotCmd = Tcl_FindCommand(interp, "::xotcl::dotdot", 0, 0); + (Tcl_ResolveCmdProc*)InterpColonCmdResolver, + InterpColonVarResolver, + (Tcl_ResolveCompiledVarProc*)InterpCompiledColonVarResolver); + RUNTIME_STATE(interp)->colonCmd = Tcl_FindCommand(interp, "::xotcl::colon", 0, 0); #endif /* Index: generic/xotcl.h =================================================================== diff -u -rfe19549734064c3a57866e7e47743ec787f647e5 -r2880a345930ceabfec83d491f26b8254099c8991 --- generic/xotcl.h (.../xotcl.h) (revision fe19549734064c3a57866e7e47743ec787f647e5) +++ generic/xotcl.h (.../xotcl.h) (revision 2880a345930ceabfec83d491f26b8254099c8991) @@ -76,7 +76,7 @@ #define CONFIGURE_ARGS_TRACE 1 #define TCL_STACK_ALLOC_TRACE 1 #define VAR_RESOLVER_TRACE 1 -#define DOT_CMD_RESOLVER_TRACE 1 +#define CMD_RESOLVER_TRACE 1 */ /* some features @@ -85,7 +85,6 @@ #define USE_COMPILED_VAR_RESOLVER 1 */ -#define USE_COLON 1 #define USE_COMPILED_VAR_RESOLVER 1 #if !defined(PRE86) Index: generic/xotclAccessInt.h =================================================================== diff -u -rf6775105babd749f662856c7eff1a903636e80e0 -r2880a345930ceabfec83d491f26b8254099c8991 --- generic/xotclAccessInt.h (.../xotclAccessInt.h) (revision f6775105babd749f662856c7eff1a903636e80e0) +++ generic/xotclAccessInt.h (.../xotclAccessInt.h) (revision 2880a345930ceabfec83d491f26b8254099c8991) @@ -14,6 +14,7 @@ #define Tcl_CallFrame_level(cf) ((CallFrame *)cf)->level #define Tcl_CallFrame_isProcCallFrame(cf) ((CallFrame *)cf)->isProcCallFrame #define Tcl_CallFrame_compiledLocals(cf) ((CallFrame *)cf)->compiledLocals +#define Tcl_CallFrame_numCompiledLocals(cf) ((CallFrame *)cf)->numCompiledLocals #define Tcl_CallFrame_callerVarPtr(cf) ((Tcl_CallFrame*)((CallFrame *)cf)->callerVarPtr) #define Tcl_CallFrame_objc(cf) ((CallFrame *)cf)->objc #define Tcl_CallFrame_objv(cf) ((CallFrame *)cf)->objv Index: generic/xotclInt.h =================================================================== diff -u -r29267f0c9db8387f58b03ffc124fc138ad88e463 -r2880a345930ceabfec83d491f26b8254099c8991 --- generic/xotclInt.h (.../xotclInt.h) (revision 29267f0c9db8387f58b03ffc124fc138ad88e463) +++ generic/xotclInt.h (.../xotclInt.h) (revision 2880a345930ceabfec83d491f26b8254099c8991) @@ -637,8 +637,7 @@ XotclStubs *xotclStubs; Tcl_CallFrame *varFramePtr; Tcl_Command cmdPtr; /* used for ACTIVE_MIXIN */ - Tcl_Command dotCmd; - Tcl_Command dotDotCmd; + Tcl_Command colonCmd; #if defined(PROFILE) XOTclProfile profile; #endif Index: generic/xotclStack85.c =================================================================== diff -u -r99b9e9e9c78df12e482d16bca08ffeb5998b3b02 -r2880a345930ceabfec83d491f26b8254099c8991 --- generic/xotclStack85.c (.../xotclStack85.c) (revision 99b9e9e9c78df12e482d16bca08ffeb5998b3b02) +++ generic/xotclStack85.c (.../xotclStack85.c) (revision 2880a345930ceabfec83d491f26b8254099c8991) @@ -95,17 +95,24 @@ static void XOTcl_PushFrameCsc2(Tcl_Interp *interp, XOTclObject *obj, XOTclCallStackContent *csc, Tcl_CallFrame *framePtr) { - /*fprintf(stderr,"PUSH CMETHOD_FRAME (XOTcl_PushFrame) frame %p\n",framePtr);*/ + /*fprintf(stderr,"PUSH CMETHOD_FRAME (XOTcl_PushFrame) frame %p obj->nsPtr %p\n",framePtr,obj->nsPtr);*/ Tcl_PushCallFrame(interp, framePtr, +#if 1 + Tcl_CallFrame_nsPtr(Tcl_Interp_varFramePtr(interp)), +#else obj->nsPtr ? obj->nsPtr : Tcl_CallFrame_nsPtr(Tcl_Interp_varFramePtr(interp)), +#endif 0|FRAME_IS_XOTCL_CMETHOD); assert(obj == csc->self); XOTcl_PushFrameSetCd(csc); } static void XOTcl_PopFrameCsc2(Tcl_Interp *interp, Tcl_CallFrame *framePtr) { + /*XOTclCallStackContent *csc = (XOTclCallStackContent *)Tcl_CallFrame_clientData(framePtr); + + fprintf(stderr,"POP CSC_FRAME (XOTcl_PopFrame) frame %p obj %p nsPtr %p\n",framePtr, csc->self, csc->self->nsPtr);*/ Tcl_PopCallFrame(interp); } @@ -434,8 +441,8 @@ #endif obj->activationCount --; - /*fprintf(stderr, "decr activationCount for %s to %d\n", objectName(csc->self), - csc->self->activationCount);*/ + /*fprintf(stderr, "decr activationCount for %s to %d csc->cl %p\n", objectName(csc->self), + csc->self->activationCount, csc->cl);*/ if (obj->activationCount < 1 && obj->flags & XOTCL_DESTROY_CALLED) { CallStackDoDestroy(interp, obj); Index: tests/aliastest.xotcl =================================================================== diff -u -r48d5751e9aeb6a4f388f6531a9248c1847b22cae -r2880a345930ceabfec83d491f26b8254099c8991 --- tests/aliastest.xotcl (.../aliastest.xotcl) (revision 48d5751e9aeb6a4f388f6531a9248c1847b22cae) +++ tests/aliastest.xotcl (.../aliastest.xotcl) (revision 2880a345930ceabfec83d491f26b8254099c8991) @@ -2,252 +2,288 @@ package require xotcl::test Test parameter count 10 +Test case alias-preliminaries { + + # The system methods of Object are either alias or forwarders + ? {lsort [::xotcl::ObjectParameterSlot info methods -methodtype alias]} {assign get} + ? {::xotcl::ObjectParameterSlot info method definition get} "::xotcl::ObjectParameterSlot alias get ::xotcl::setinstvar" -# The system methods of Object are either alias or forwarders -? {lsort [::xotcl::ObjectParameterSlot info methods -methodtype alias]} {assign get} -? {::xotcl::ObjectParameterSlot info method definition get} "::xotcl::ObjectParameterSlot alias get ::xotcl::setinstvar" - -# define an alias and retrieve its definition -set cmd "::xotcl2::Object alias -objscope set ::set" -eval $cmd -? {Object info method definition set} $cmd - -# define an alias and retrieve its definition -Class create Base { - :method foo {{-x 1}} {return $x} + # define an alias and retrieve its definition + set cmd "::xotcl2::Object alias -objscope set ::set" + eval $cmd + ? {Object info method definition set} $cmd + } -Class create Foo -::xotcl::alias ::Foo foo ::xotcl::classes::Base::foo +Test case alias-simple { + # define an alias and retrieve its definition + Class create Base { + :method foo {{-x 1}} {return $x} + } -? {Foo info method definition foo} "::Foo alias foo ::xotcl::classes::Base::foo" + Class create Foo + ::xotcl::alias ::Foo foo ::xotcl::classes::Base::foo + + ? {Foo info method definition foo} "::Foo alias foo ::xotcl::classes::Base::foo" + + Foo create f1 + ? {f1 foo} 1 + ? {f1 foo -x 2} 2 + ? {Foo info methods -methodtype alias} "foo" + + ? {Base info methods -methodtype scripted} {foo} + ? {Foo info methods -methodtype scripted} {} + ? {Foo info methods -methodtype alias} {foo} + Base method foo {} {} + ? {Foo info methods -methodtype alias} "" + ? {Base info methods -methodtype scripted} {} + ? {Foo info methods -methodtype scripted} {} + ? {Foo info method definition foo} "" + -Foo create f1 -? {f1 foo} 1 -? {f1 foo -x 2} 2 -? {Foo info methods -methodtype alias} "foo" + Base method foo {{-x 1}} {return $x} + ::xotcl::alias ::Foo foo ::xotcl::classes::Base::foo + + ? {Base info methods -methodtype scripted} {foo} "defined again" + ? {Foo info methods -methodtype alias} {foo} "aliased again" + Foo method foo {} {} + ? {Base info methods -methodtype scripted} {foo} "still defined" + ? {Foo info methods -methodtype alias} {} "removed" +} -? {Base info methods -methodtype scripted} {foo} -? {Foo info methods -methodtype scripted} {} -? {Foo info methods -methodtype alias} {foo} -Base method foo {} {} -? {Foo info methods -methodtype alias} "" -? {Base info methods -methodtype scripted} {} -? {Foo info methods -methodtype scripted} {} -? {Foo info method definition foo} "" +Test case alias-chaining { + # + # chaining aliases + # + + Class create T + Class create S + T create t + S create s + + + T method foo args { return [self class]->[self proc] } + ::xotcl::alias T FOO ::xotcl::classes::T::foo + + ? {t foo} ::T->foo + ? {t FOO} ::T->foo + + ? {lsort [T info methods]} {FOO foo} + T method foo {} {} + ? {lsort [T info methods]} {} "alias is deleted" + + # puts stderr "double indirection" + T method foo args { return [self class]->[self proc] } + ::xotcl::alias T FOO ::xotcl::classes::T::foo + ::xotcl::alias S BAR ::xotcl::classes::T::FOO + + ? {T info methods -methodtype alias} "FOO" + ? {T info method definition FOO} "::T alias FOO ::xotcl::classes::T::foo" + ? {lsort [T info methods]} {FOO foo} + ? {S info methods} {BAR} + T method FOO {} {} + ? {T info methods} {foo} + ? {S info methods} {BAR} + ? {s BAR} ::S->foo + ? {t foo} ::T->foo + ? {S info method definition BAR} "::S alias BAR ::xotcl::classes::T::FOO" + + + T method foo {} {} + ? {T info methods} {} + ? {S info methods} {} + + T method foo args { return [self class]->[self proc] } + ::xotcl::alias T FOO ::xotcl::classes::T::foo + ::xotcl::alias S BAR ::xotcl::classes::T::FOO + + ? {lsort [T info methods]} {FOO foo} + ? {S info methods} {BAR} + T method foo {} {} + ? {S info methods} {} + ? {T info methods} {} + + T method foo args { return [self class]->[self proc] } + T object method bar args { return [self class]->[self proc] } + ::xotcl::alias T -per-object FOO ::xotcl::classes::T::foo + ::xotcl::alias T -per-object BAR ::T::FOO + ::xotcl::alias T -per-object ZAP ::T::BAR + ? {T info methods} {foo} + ? {lsort [T object info methods -methodtype alias]} {BAR FOO ZAP} + ? {lsort [T object info methods]} {BAR FOO ZAP bar} + ? {t foo} ::T->foo + ? {T object info method definition ZAP} {::T object alias ZAP ::T::BAR} + + ? {T FOO} ->foo + ? {T BAR} ->foo + ? {T ZAP} ->foo + ? {T bar} ->bar + T object method FOO {} {} + ? {T info methods} {foo} + ? {lsort [T object info methods]} {BAR ZAP bar} + ? {T BAR} ->foo + ? {T ZAP} ->foo + rename ::T::BAR "" + ? {T info methods} {foo} + ? {lsort [T object info methods]} {ZAP bar} + #? {T BAR} ""; # now calling the proc defined above, alias chain seems intact + ? {T ZAP} ->foo; # is ok, still pointing to 'foo' + #T object method BAR {} {} + ? {T info methods} {foo} + ? {lsort [T object info methods]} {ZAP bar} + ? {T ZAP} ->foo + T method foo {} {} + ? {T info methods} {} + ? {lsort [T object info methods]} {bar} +} +Test case alias-per-object { -Base method foo {{-x 1}} {return $x} -::xotcl::alias ::Foo foo ::xotcl::classes::Base::foo + Class create T { + :object method bar args { return [self class]->[self proc] } + :create t + } + proc ::foo args { return [self class]->[self proc] } -? {Base info methods -methodtype scripted} {foo} "defined again" -? {Foo info methods -methodtype alias} {foo} "aliased again" -Foo method foo {} {} -? {Base info methods -methodtype scripted} {foo} "still defined" -? {Foo info methods -methodtype alias} {} "removed" + # + # per-object methods as per-object aliases + # + T object method m1 args { return [self class]->[self proc] } + ::xotcl::alias T -per-object M1 ::T::m1 + ::xotcl::alias T -per-object M11 ::T::M1 + ? {lsort [T object info methods]} {M1 M11 bar m1} + ? {T m1} ->m1 + ? {T M1} ->m1 + ? {T M11} ->m1 + T object method M1 {} {} + ? {lsort [T object info methods]} {M11 bar m1} + ? {T m1} ->m1 + ? {T M11} ->m1 + T object method m1 {} {} + ? {lsort [T object info methods]} {bar} + + # + # a proc as alias + # + + proc foo args { return [self class]->[self proc] } + ::xotcl::alias T FOO1 ::foo + ::xotcl::alias T -per-object FOO2 ::foo + # + # ! per-object alias referenced as per-class alias ! + # + ::xotcl::alias T BAR ::T::FOO2 + ? {lsort [T object info methods]} {FOO2 bar} + ? {lsort [T info methods]} {BAR FOO1} + ? {T FOO2} ->foo + ? {t FOO1} ::T->foo + ? {t BAR} ::T->foo + # + # delete proc + # + rename ::foo "" + ? {lsort [T object info methods]} {bar} + ? {lsort [T info methods]} {} +} -# -# chaining aliases -# -Class create T -Class create S -T create t -S create s - - -T method foo args { return [self class]->[self proc] } -::xotcl::alias T FOO ::xotcl::classes::T::foo - -? {t foo} ::T->foo -? {t FOO} ::T->foo - -? {lsort [T info methods]} {FOO foo} -T method foo {} {} -? {lsort [T info methods]} {} "alias is deleted" - -# puts stderr "double indirection" -T method foo args { return [self class]->[self proc] } -::xotcl::alias T FOO ::xotcl::classes::T::foo -::xotcl::alias S BAR ::xotcl::classes::T::FOO - -? {T info methods -methodtype alias} "FOO" -? {T info method definition FOO} "::T alias FOO ::xotcl::classes::T::foo" -? {lsort [T info methods]} {FOO foo} -? {S info methods} {BAR} -T method FOO {} {} -? {T info methods} {foo} -? {S info methods} {BAR} -? {s BAR} ::S->foo -? {t foo} ::T->foo -? {S info method definition BAR} "::S alias BAR ::xotcl::classes::T::FOO" - - -T method foo {} {} -? {T info methods} {} -? {S info methods} {} - -T method foo args { return [self class]->[self proc] } -::xotcl::alias T FOO ::xotcl::classes::T::foo -::xotcl::alias S BAR ::xotcl::classes::T::FOO - -? {lsort [T info methods]} {FOO foo} -? {S info methods} {BAR} -T method foo {} {} -? {S info methods} {} -? {T info methods} {} - -T method foo args { return [self class]->[self proc] } -T object method bar args { return [self class]->[self proc] } -::xotcl::alias T -per-object FOO ::xotcl::classes::T::foo -::xotcl::alias T -per-object BAR ::T::FOO -::xotcl::alias T -per-object ZAP ::T::BAR -? {T info methods} {foo} -? {lsort [T object info methods -methodtype alias]} {BAR FOO ZAP} -? {lsort [T object info methods]} {BAR FOO ZAP bar} -? {t foo} ::T->foo -? {T object info method definition ZAP} {::T object alias ZAP ::T::BAR} - -? {T FOO} ->foo -? {T BAR} ->foo -? {T ZAP} ->foo -? {T bar} ->bar -T object method FOO {} {} -? {T info methods} {foo} -? {lsort [T object info methods]} {BAR ZAP bar} -? {T BAR} ->foo -? {T ZAP} ->foo -rename ::T::BAR "" -? {T info methods} {foo} -? {lsort [T object info methods]} {ZAP bar} -#? {T BAR} ""; # now calling the proc defined above, alias chain seems intact -? {T ZAP} ->foo; # is ok, still pointing to 'foo' -#T object method BAR {} {} -? {T info methods} {foo} -? {lsort [T object info methods]} {ZAP bar} -? {T ZAP} ->foo -T method foo {} {} -? {T info methods} {} -? {lsort [T object info methods]} {bar} - -# -# per-object methods as per-object aliases -# -T object method m1 args { return [self class]->[self proc] } -::xotcl::alias T -per-object M1 ::T::m1 -::xotcl::alias T -per-object M11 ::T::M1 -? {lsort [T object info methods]} {M1 M11 bar m1} -? {T m1} ->m1 -? {T M1} ->m1 -? {T M11} ->m1 -T object method M1 {} {} -? {lsort [T object info methods]} {M11 bar m1} -? {T m1} ->m1 -? {T M11} ->m1 -T object method m1 {} {} -? {lsort [T object info methods]} {bar} - -# -# a proc as alias -# - -proc foo args { return [self class]->[self proc] } -::xotcl::alias T FOO1 ::foo -::xotcl::alias T -per-object FOO2 ::foo -# -# ! per-object alias referenced as per-class alias ! -# -::xotcl::alias T BAR ::T::FOO2 -? {lsort [T object info methods]} {FOO2 bar} -? {lsort [T info methods]} {BAR FOO1} -? {T FOO2} ->foo -? {t FOO1} ::T->foo -? {t BAR} ::T->foo -# -# delete proc -# -rename foo "" -? {lsort [T object info methods]} {bar} -? {lsort [T info methods]} {} - # namespaced procs + namespace deletion +Test case alias-namespaced { + Class create T { + :object method bar args { return [self class]->[self proc] } + :create t + } + + namespace eval ::ns1 { + proc foo args { return [self class]->[self proc] } + proc bar args { return [uplevel 2 {set _}] } + proc bar2 args { upvar 2 _ __; return $__} + } + + ::xotcl::alias T FOO ::ns1::foo + ::xotcl::alias T BAR ::ns1::bar + ::xotcl::alias T BAR2 ::ns1::bar2 + ? {lsort [T info methods]} {BAR BAR2 FOO} + set ::_ GOTYA + ? {t FOO} ::T->foo + ? {t BAR} GOTYA + ? {t BAR2} GOTYA + namespace delete ::ns1 + ? {info procs ::ns1::*} {} + ? {lsort [T info methods]} {} + + # per-object namespaces + + Class create U + U create u + ? {namespace exists ::U} 0 + U object method zap args { return [self class]->[self proc] } + ::xotcl::alias ::U -per-object ZAP ::U::zap + U requireNamespace + ? {namespace exists ::U} 1 + + U object method bar args { return [self class]->[self proc] } + ::xotcl::alias U -per-object BAR ::U::bar + ? {lsort [U object info methods]} {BAR ZAP bar zap} + ? {U BAR} ->bar + ? {U ZAP} ->zap + namespace delete ::U + ? {namespace exists ::U} 0 + ? {lsort [U object info methods]} {} + ? {U info callable BAR} "" + ? {U info callable ZAP} "" + + ::U destroy +} -namespace eval ::ns1 { - proc foo args { return [self class]->[self proc] } - proc bar args { return [uplevel 2 {set _}] } - proc bar2 args { upvar 2 _ __; return $__} +Class create V { + set :z 1 } +? {lsort [V info vars]} {z} -::xotcl::alias T FOO ::ns1::foo -::xotcl::alias T BAR ::ns1::bar -::xotcl::alias T BAR2 ::ns1::bar2 -? {lsort [T info methods]} {BAR BAR2 FOO} -set _ GOTYA -? {t FOO} ::T->foo -? {t BAR} GOTYA -? {t BAR2} GOTYA -namespace delete ::ns1 -? {info procs ::ns1::*} {} -? {lsort [T info methods]} {} -# per-object namespaces +# dot-resolver/ dot-dispatcher used in aliased proc -Class create U -U create u -? {namespace exists ::U} 0 -U object method zap args { return [self class]->[self proc] } -::xotcl::alias ::U -per-object ZAP ::U::zap -U requireNamespace -? {namespace exists ::U} 1 +Test case alias-dot-resolver { -U object method bar args { return [self class]->[self proc] } -::xotcl::alias U -per-object BAR ::U::bar -? {lsort [U object info methods]} {BAR ZAP bar zap} -? {U BAR} ->bar -? {U ZAP} ->zap -namespace delete ::U -? {namespace exists ::U} 0 -? {lsort [U object info methods]} {} -? {U info callable BAR} "" -? {U info callable ZAP} "" + Class create V { + set :z 1 + :method bar {z} { return $z } + :object method bar {z} { return $z } + :create v { + set :z 2 + } + } + ? {lsort [V info vars]} {z} + puts stderr =====1 -::U destroy + puts stderr =====0 + ? {lsort [V info vars]} {z} + ? {lsort [v info vars]} {z} -# dot-resolver/ dot-dispatcher used in aliased proc + proc ::foo args { return [:bar ${:z}]-[set :z]-[my bar [set :z]] } -Class create V { - set :z 1 -} + ::xotcl::alias V FOO1 ::foo + ::xotcl::alias V -per-object FOO2 ::foo -V create v { - set :z 2 + ? {lsort [V object info methods]} {FOO2 bar} + ? {lsort [V info methods]} {FOO1 bar} +puts stderr =====1 + ? {V FOO2} 1-1-1 + ? {v FOO1} 2-2-2 + V method FOO1 {} {} + ? {lsort [V info methods]} {bar} + rename ::foo "" + ? {lsort [V object info methods]} {bar} } -V method bar {z} { return $z } -V object method bar {z} { return $z } - -proc foo args { return [:bar ${:z}]-[set :z]-[my bar [set :z]] } - -::xotcl::alias V FOO1 ::foo -::xotcl::alias V -per-object FOO2 ::foo -? {lsort [V object info methods]} {FOO2 bar} -? {lsort [V info methods]} {FOO1 bar} -? {V FOO2} 1-1-1 -? {v FOO1} 2-2-2 -V method FOO1 {} {} -? {lsort [V info methods]} {bar} -rename ::foo "" -? {lsort [V object info methods]} {bar} - - # # Tests for the ::xotcl::alias store, used for introspection for # aliases. The alias store (an associative variable) is mostly # necessary for for the direct aliases (e.g. aliases to C implemented # tcl commands), for which we have no stubs at the place where the # alias was registered. # -::xotcl::use xotcl2 # # structure of the ::xotcl::alias store: Index: tests/object-system.xotcl =================================================================== diff -u -r217d826e64107056ae97176552cae3c776991b9e -r2880a345930ceabfec83d491f26b8254099c8991 --- tests/object-system.xotcl (.../object-system.xotcl) (revision 217d826e64107056ae97176552cae3c776991b9e) +++ tests/object-system.xotcl (.../object-system.xotcl) (revision 2880a345930ceabfec83d491f26b8254099c8991) @@ -10,7 +10,7 @@ if {$msg eq ""} {set msg $cmd} if {$r ne $expected} { puts stderr "ERROR $msg returned '$r' ne '$expected'" - exit + error "FAILED $msg returned '$r' ne '$expected'" } else { puts stderr "OK $msg" } @@ -81,15 +81,29 @@ # basic parameter tests Class C -parameter {{x 1} {y 2}} +? {::xotcl::objectproperty C object} 1 +? {::xotcl::objectproperty C::slot object} 1 +? {C info children} ::C::slot + +puts stderr ====COPY C copy X +puts stderr ====0a +? {::xotcl::objectproperty X object} 1 +? {X info vars} "" +? {C info vars} "" +puts stderr ====0b +? {::xotcl::objectproperty X::slot object} 1 +puts stderr ====0c ? {C::slot info vars} __parameter ? {C info parameter} {{x 1} {y 2}} +puts stderr ====1 ? {X::slot info vars} __parameter +puts stderr ====2 ? {X info parameter} {{x 1} {y 2}} +puts stderr ====3 - # # tests for the dispatch command Index: tests/varresolutiontest.xotcl =================================================================== diff -u -r930db9f3c2dc7b83ba64cbb1c600242ed650adab -r2880a345930ceabfec83d491f26b8254099c8991 --- tests/varresolutiontest.xotcl (.../varresolutiontest.xotcl) (revision 930db9f3c2dc7b83ba64cbb1c600242ed650adab) +++ tests/varresolutiontest.xotcl (.../varresolutiontest.xotcl) (revision 2880a345930ceabfec83d491f26b8254099c8991) @@ -71,9 +71,11 @@ Object create o o requireNamespace - +puts stderr =======1 o set x 1 +puts stderr =======2 ? {namespace eval ::o set x} 1 +puts stderr =======3 ? {::o set x} 1 ? {namespace eval ::o set x 3} 3 ? {::o set x} 3 @@ -390,7 +392,9 @@ set :d 1 } ? {o exists d} 1 -? {o exists ddd} 1 ;# TODO: should be 0 +puts stderr ====111 +? {o exists ddd} 0 +puts stderr ====222 # softeval2 never sets variables o softeval2 { @@ -399,7 +403,7 @@ } ? {o exists z} 0 ? {o exists zzz} 0 -? {lsort [o info vars]} "c ccc d ddd" +? {lsort [o info vars]} "c ccc d" o destroy ################################################## @@ -524,4 +528,44 @@ puts stderr "mixin add M" C mixin add M2 ? {::xotcl::relation C class-mixin} "::module::M2 ::module::M1" +} + + +################################################## +# test setting of instance variables for +# objects with namespaces in and outside +# of an eval (one case uses compiler) +################################################## + +Test case alias-dot-resolver-interp +# outside of eval scope (interpreted) +Class create V { + set :Z 1 + set ZZZ 1 + :method bar {z} { return $z } + :object method bar {z} { return $z } + :create v { + set zzz 2 + set :z 2 + } +} +? {lsort [V info vars]} {Z} +? {lsort [v info vars]} {z} + +# dot-resolver/ dot-dispatcher used in aliased proc + +Test case alias-dot-resolver { + + Class create V { + set :Z 1 + set ZZZ 1 + :method bar {z} { return $z } + :object method bar {z} { return $z } + :create v { + set :z 2 + set zzz 2 + } + } + ? {lsort [V info vars]} {Z ZZZ}; #TODO: should be Z + ? {lsort [v info vars]} {z zzz} ; #TODO: should be z } \ No newline at end of file