Posted to tcl by apw at Mon Jul 23 10:09:50 GMT 2007view pretty

ndex: tclOOInt.h
===================================================================
RCS file: /cvsroot/tcl/oocore/generic/tclOOInt.h,v
retrieving revision 1.8
diff -b -u -r1.8 tclOOInt.h
--- tclOOInt.h	25 Jun 2007 14:20:20 -0000	1.8
+++ tclOOInt.h	23 Jul 2007 09:55:36 -0000
@@ -131,6 +131,12 @@
     Tcl_Obj *cachedNameObj;	/* Cache of the name of the object. */
     Tcl_HashTable publicContextCache;	/* Place to keep unused contexts. */
     Tcl_HashTable privateContextCache;	/* Place to keep unused contexts. */
+#ifdef ARNULF_FOR_ITCL_CODE
+    Tcl_Resolve *resolvePtr;
+                                /* Points to a struct for resolving commands
+				 * and variables
+				 */
+#endif
 } Object;

 #define OBJECT_DELETED	1	/* Flag to say that an object has been
@@ -378,7 +384,7 @@
 			    CallContext *contextPtr);
 MODULE_SCOPE CallContext *TclOOGetCallContext(Foundation *fPtr, Object *oPtr,
 			    Tcl_Obj *methodNameObj, int flags,
-			    Tcl_HashTable *cachePtr);
+			    Tcl_HashTable *cachePtr, Class *clsPtr);
 MODULE_SCOPE int	TclOOInvokeContext(Tcl_Interp *interp,
 			    CallContext *contextPtr, int objc,
 			    Tcl_Obj *const *objv);
Index: tclOO.c
===================================================================
RCS file: /cvsroot/tcl/oocore/generic/tclOO.c,v
retrieving revision 1.20
diff -b -u -r1.20 tclOO.c
--- tclOO.c	16 Jun 2007 14:53:08 -0000	1.20
+++ tclOO.c	23 Jul 2007 09:55:50 -0000
@@ -397,6 +397,9 @@
     oPtr->flags = 0;
     oPtr->creationEpoch = creationEpoch;
     oPtr->metadataPtr = NULL;
+#ifdef ARNULF_FOR_ITCL_CODE
+    oPtr->resolvePtr = NULL;
+#endif

     /*
      * Initialize the traces.
@@ -479,7 +482,7 @@
     if (!Tcl_InterpDeleted(interp)) {
 	CallContext *contextPtr =
 		TclOOGetCallContext(TclOOGetFoundation(interp), oPtr, NULL,
-		DESTRUCTOR, NULL);
+		DESTRUCTOR, NULL, NULL);

 	if (contextPtr != NULL) {
 	    int result;
@@ -717,6 +720,11 @@
 	ckfree((char *) oPtr->metadataPtr);
 	oPtr->metadataPtr = NULL;
     }
+#ifdef ARNULF_FOR_ITCL_CODE
+    if (oPtr->resolvePtr != NULL) {
+	ckfree((char *) oPtr->resolvePtr);
+    }
+#endif

     if (clsPtr != NULL && !(oPtr->flags & ROOT_OBJECT)) {
 	Class *superPtr, *mixinPtr;
@@ -1162,7 +1170,7 @@

     if (objc >= 0) {
 	contextPtr = TclOOGetCallContext(TclOOGetFoundation(interp), oPtr,
-		NULL, CONSTRUCTOR, NULL);
+		NULL, CONSTRUCTOR, NULL, NULL);
 	if (contextPtr != NULL) {
 	    int result;
 	    Tcl_InterpState state;
@@ -1675,6 +1683,7 @@
     int objc,
     Tcl_Obj *const *objv)
 {
+
     return ObjectCmd(clientData, interp, objc, objv, PUBLIC_METHOD,
 	    &((Object *)clientData)->publicContextCache);
 }
@@ -1690,6 +1699,7 @@
 	    &((Object *)clientData)->privateContextCache);
 }

+void            InitClassHierarchy(Foundation *fPtr, Class *classPtr);
 static int
 ObjectCmd(
     Object *oPtr,		/* The object being invoked. */
@@ -1701,6 +1711,13 @@
     Tcl_HashTable *cachePtr)	/* What call chain cache to use. */
 {
     CallContext *contextPtr;
+    Class *clsPtr;
+    Class *superPtr;
+    Tcl_Obj *objName;
+    char *sp;
+    char *cp;
+    Tcl_Obj *className;
+    int i;
     int result;

     if (objc < 2) {
@@ -1708,8 +1725,34 @@
 	return TCL_ERROR;
     }

+    clsPtr = NULL;
+    objName = NULL;
+    className = NULL;
+    if (objv[1] != NULL) {
+	sp = Tcl_GetString(objv[1]);
+        cp = strstr(sp, "::");
+	if (cp != NULL) {
+	    objName = Tcl_NewStringObj(cp+2, -1);
+	    InitClassHierarchy(TclOOGetFoundation(interp), oPtr->selfCls);
+	    className = Tcl_NewStringObj(sp, cp-sp);
+	    Tcl_IncrRefCount(className);
+	    sp = Tcl_GetString(className);
+	    if (strcmp(oPtr->selfCls->thisPtr->namespacePtr->name, sp) != 0) {
+	        FOREACH(superPtr, oPtr->selfCls->superclasses) {
+		    if (strcmp(superPtr->thisPtr->namespacePtr->name, sp) == 0) {
+			clsPtr = superPtr;
+		        break;
+		    }
+		    
+		}
+	    } else {
+	        clsPtr = oPtr->selfCls;
+            }
+	    Tcl_DecrRefCount(className);
+	}
+    }
     contextPtr = TclOOGetCallContext(TclOOGetFoundation(interp), oPtr,
-	    objv[1], flags | (oPtr->flags & FILTER_HANDLING), cachePtr);
+	    objName == NULL ? objv[1] : objName, flags | (oPtr->flags & FILTER_HANDLING), cachePtr, clsPtr);
     if (contextPtr == NULL) {
 	Tcl_AppendResult(interp, "impossible to invoke method \"",
 		TclGetString(objv[1]),
Index: tclOOMethod.c
===================================================================
RCS file: /cvsroot/tcl/oocore/generic/tclOOMethod.c,v
retrieving revision 1.4
diff -b -u -r1.4 tclOOMethod.c
--- tclOOMethod.c	25 Jun 2007 14:20:21 -0000	1.4
+++ tclOOMethod.c	23 Jul 2007 09:55:57 -0000
@@ -583,6 +583,9 @@
     if (pmPtr->flags & USE_DECLARER_NS) {
 	register Method *mPtr = contextPtr->callChain[contextPtr->index].mPtr;

+#ifdef ARNULF_FOR_ITCL_CODE
+        flags |= FRAME_HAS_RESOLVER;
+#endif
 	if (mPtr->declaringClassPtr != NULL) {
 	    nsPtr = mPtr->declaringClassPtr->thisPtr->namespacePtr;
 	} else {
@@ -615,6 +618,40 @@
     framePtr->objv = objv;	/* ref counts for args are incremented below */
     framePtr->procPtr = pmPtr->procPtr;

+#ifdef ARNULF_FOR_ITCL_CODE
+    if (flags & FRAME_HAS_RESOLVER) {
+	Tcl_DString buffer;
+	Tcl_Resolve *resolvePtr;
+	Tcl_Namespace *varNsPtr;
+
+	if (flags & FRAME_IS_CONSTRUCTOR) {
+	    Tcl_DStringInit(&buffer);
+	    Tcl_DStringAppend(&buffer, "::itcl::variables::", -1);
+	    Tcl_DStringAppend(&buffer,
+	            Tcl_GetCommandName(interp, oPtr->command), -1);
+	    varNsPtr = Tcl_FindNamespace(interp, Tcl_DStringValue(&buffer),
+	            NULL, 0);
+//fprintf(stderr, "CONVNS3!%s!%p\n", Tcl_DStringValue(&buffer), varNsPtr);
+            if (varNsPtr != NULL) {
+	        SetVarResolver((Tcl_Object)oPtr, varNsPtr);
+	    }
+	    Tcl_DStringFree(&buffer);
+	}
+	resolvePtr = oPtr->resolvePtr;
+	if ((resolvePtr != NULL) &&
+	        (oPtr->resolvePtr->objectVarNsPtr != NULL)) { 
+	    Tcl_DStringInit(&buffer);
+	    Tcl_DStringAppend(&buffer,
+	            oPtr->resolvePtr->objectVarNsPtr->fullName, -1);
+	    Tcl_DStringAppend(&buffer, nsPtr->fullName, -1);
+	    oPtr->resolvePtr->varNsPtr = Tcl_FindNamespace(interp,
+	            Tcl_DStringValue(&buffer), NULL, 0);
+//fprintf(stderr, "FN!%s!%p\n", Tcl_DStringValue(&buffer), oPtr->resolvePtr->varNsPtr);
+	    Tcl_DStringFree(&buffer);
+	}
+        framePtr->resolvePtr = oPtr->resolvePtr;
+    }
+#endif
     /*
      * Finish filling out the extra frame info.
      */
@@ -1148,6 +1185,22 @@
     return (((Method *)method)->flags & PUBLIC_METHOD) ? 1 : 0;
 }

+#ifdef ARNULF_FOR_ITCL_CODE
+void
+SetVarResolver(
+    Tcl_Object oPtr,
+    Tcl_Namespace *nsPtr)
+{
+    if (oPtr != NULL) {
+	Tcl_Resolve *resolvePtr;
+	resolvePtr = (Tcl_Resolve *) ckalloc(sizeof(Tcl_Resolve));
+	resolvePtr->objectVarNsPtr = nsPtr;
+	resolvePtr->varNsPtr = NULL;
+        ((Object*)oPtr)->resolvePtr = resolvePtr;
+    }
+}
+#endif
+
 /*
  * Local Variables:
  * mode: c
Index: tclOODefineCmds.c
===================================================================
RCS file: /cvsroot/tcl/oocore/generic/tclOODefineCmds.c,v
retrieving revision 1.1
diff -b -u -r1.1 tclOODefineCmds.c
--- tclOODefineCmds.c	18 May 2007 13:17:15 -0000	1.1
+++ tclOODefineCmds.c	23 Jul 2007 09:56:06 -0000
@@ -154,12 +154,16 @@
     Object *oPtr;
     Class *clsPtr;
     int bodyLength;
+    int use_declarer_ns_flag = 0;

-    if (objc != 3) {
+    if ((objc != 3) && (objc != 4)) {
 	Tcl_WrongNumArgs(interp, 1, objv, "arguments body");
 	return TCL_ERROR;
     }

+    if (objc > 3) {
+        use_declarer_ns_flag = USE_DECLARER_NS;
+    }
     /*
      * Extract and validate the context, which is the class that we wish to
      * modify.
@@ -184,7 +188,7 @@

 	Method *mPtr;

-	mPtr = TclOONewProcClassMethod(interp, clsPtr, PUBLIC_METHOD, NULL,
+	mPtr = TclOONewProcClassMethod(interp, clsPtr, PUBLIC_METHOD|use_declarer_ns_flag, NULL,
 		objv[1], objv[2]);
 	if (mPtr == NULL) {
 	    return TCL_ERROR;
@@ -221,12 +225,16 @@
     Object *oPtr;
     Class *clsPtr;
     int bodyLength;
+    int use_declarer_ns_flag = 0;

-    if (objc != 2) {
+    if ((objc != 2) && (objc != 3)) {
 	Tcl_WrongNumArgs(interp, 1, objv, "body");
 	return TCL_ERROR;
     }

+    if (objc > 2) {
+        use_declarer_ns_flag = USE_DECLARER_NS;
+    }
     oPtr = (Object *) TclOOGetDefineCmdContext(interp);
     if (oPtr == NULL) {
 	return TCL_ERROR;
@@ -246,7 +254,7 @@

 	Method *mPtr;

-	mPtr = TclOONewProcClassMethod(interp, clsPtr, PUBLIC_METHOD, NULL,
+	mPtr = TclOONewProcClassMethod(interp, clsPtr, PUBLIC_METHOD|use_declarer_ns_flag, NULL,
 		NULL, objv[1]);
 	if (mPtr == NULL) {
 	    return TCL_ERROR;
@@ -482,12 +490,16 @@
     int isSelfMethod = (clientData != NULL);
     Object *oPtr;
     int bodyLength;
+    int use_declarer_ns_flag = 0;

-    if (objc != 4) {
-	Tcl_WrongNumArgs(interp, 1, objv, "name args body");
+    if (objc != 4 && objc != 5) {
+	Tcl_WrongNumArgs(interp, 1, objv, "name args body ?flag?");
 	return TCL_ERROR;
     }

+    if (objc > 4) {
+        use_declarer_ns_flag = USE_DECLARER_NS;
+    }
     oPtr = (Object *) TclOOGetDefineCmdContext(interp);
     if (oPtr == NULL) {
 	return TCL_ERROR;
@@ -504,6 +516,7 @@
 	int isPublic = Tcl_StringMatch(TclGetString(objv[1]), "[a-z]*")
 		? PUBLIC_METHOD : 0;

+isPublic |= use_declarer_ns_flag;
 	if (isSelfMethod) {
 	    mPtr = TclOONewProcMethod(interp, oPtr, isPublic, objv[1],
 		    objv[2], objv[3]);
Index: tclOOCall.c
===================================================================
RCS file: /cvsroot/tcl/oocore/generic/tclOOCall.c,v
retrieving revision 1.2
diff -b -u -r1.2 tclOOCall.c
--- tclOOCall.c	15 Jun 2007 14:26:03 -0000	1.2
+++ tclOOCall.c	23 Jul 2007 09:56:11 -0000
@@ -51,13 +51,13 @@
 static void		AddSimpleChainToCallContext(Object *oPtr,
 			    Tcl_Obj *methodNameObj, struct ChainBuilder *cbPtr,
 			    Tcl_HashTable *doneFilters, int isPublic,
-			    Class *filterDecl);
+			    Class *filterDecl, Class *clsPtr);
 static void		AddSimpleClassChainToCallContext(Class *classPtr,
 			    Tcl_Obj *methodNameObj, struct ChainBuilder *cbPtr,
 			    Tcl_HashTable *doneFilters, int isPublic,
 			    Class *filterDecl);
 static int		CmpStr(const void *ptr1, const void *ptr2);
-static void		InitClassHierarchy(Foundation *fPtr, Class *classPtr);
+void		InitClassHierarchy(Foundation *fPtr, Class *classPtr);
 static void		DupMethodNameRep(Tcl_Obj *srcPtr, Tcl_Obj *dstPtr);
 static void		FreeMethodNameRep(Tcl_Obj *objPtr);

@@ -244,7 +244,7 @@
  * ----------------------------------------------------------------------
  */

-static void
+void
 InitClassHierarchy(
     Foundation *fPtr,
     Class *classPtr)
@@ -532,8 +532,9 @@
 				 * Only the bits PUBLIC_METHOD, CONSTRUCTOR,
 				 * PRIVATE_METHOD, DESTRUCTOR and
 				 * FILTER_HANDLING are useful. */
-    Tcl_HashTable *cachePtr)	/* Where to cache the chain. Ignored for both
+    Tcl_HashTable *cachePtr,	/* Where to cache the chain. Ignored for both
 				 * constructors and destructors. */
+    Class *clsPtr)              /* class if direct call with classname in front */
 {
     struct ChainBuilder cb;
     int i, count, doFilters;
@@ -608,7 +609,7 @@
 	}
 	FOREACH(filterObj, oPtr->filters) {
 	    AddSimpleChainToCallContext(oPtr, filterObj, &cb, &doneFilters, 0,
-		    NULL);
+		    NULL, NULL);
 	}
 	AddClassFiltersToCallContext(oPtr, oPtr->selfCls, &cb, &doneFilters);
 	Tcl_DeleteHashTable(&doneFilters);
@@ -619,7 +620,7 @@
      * Add the actual method implementations.
      */

-    AddSimpleChainToCallContext(oPtr, methodNameObj, &cb, NULL, flags, NULL);
+    AddSimpleChainToCallContext(oPtr, methodNameObj, &cb, NULL, flags, NULL, clsPtr);

     /*
      * Check to see if the method has no implementation. If so, we probably
@@ -638,7 +639,7 @@
 	    return NULL;
 	}
 	AddSimpleChainToCallContext(oPtr, fPtr->unknownMethodNameObj, &cb,
-		NULL, 0, NULL);
+		NULL, 0, NULL, NULL);
 	cb.contextPtr->flags |= OO_UNKNOWN_METHOD;
 	cb.contextPtr->globalEpoch = -1;
 	if (count == cb.contextPtr->numCallChain) {
@@ -697,7 +698,7 @@
 	(void) Tcl_CreateHashEntry(doneFilters, (char *) filterObj, &isNew);
 	if (isNew) {
 	    AddSimpleChainToCallContext(oPtr, filterObj, cbPtr, doneFilters,
-		    0, clsPtr);
+		    0, clsPtr, NULL);
 	}
     }

@@ -740,9 +741,10 @@
     Tcl_HashTable *doneFilters,	/* Where to record what call chain entries
 				 * have been processed. */
     int flags,			/* What sort of call chain are we building. */
-    Class *filterDecl)		/* The class that declared the filter. If
+    Class *filterDecl,		/* The class that declared the filter. If
 				 * NULL, either the filter was declared by the
 				 * object or this isn't a filter. */
+    Class *clsPtr)              /* class for direct call */
 {
     int i;

@@ -776,7 +778,7 @@
 	    AddSimpleClassChainToCallContext(mixinPtr, methodNameObj, cbPtr,
 		    doneFilters, flags, filterDecl);
 	}
-	FOREACH(superPtr, oPtr->selfCls->classHierarchy) {
+	FOREACH(superPtr, clsPtr == NULL ? oPtr->selfCls->classHierarchy : clsPtr->classHierarchy) {
 	    int j=i;		/* HACK: save index so can nest FOREACHes. */
 	    FOREACH(mixinPtr, superPtr->mixins) {
 		AddSimpleClassChainToCallContext(mixinPtr, methodNameObj,
@@ -790,8 +792,8 @@
 		    filterDecl);
 	}
     }
-    AddSimpleClassChainToCallContext(oPtr->selfCls, methodNameObj, cbPtr,
-	    doneFilters, flags, filterDecl);
+    AddSimpleClassChainToCallContext(clsPtr == NULL ? oPtr->selfCls : clsPtr,
+            methodNameObj, cbPtr, doneFilters, flags, filterDecl);
 }

 /*