diff -urp rdnzl-0.11.2\arrays.lisp rdnzl\arrays.lisp --- rdnzl-0.11.2\arrays.lisp Sat Jan 26 23:28:30 2008 +++ rdnzl\arrays.lisp Tue Feb 12 01:40:29 2008 @@ -75,9 +75,9 @@ CONTAINER) and DIMENSIONS dimensions." (defun list-to-rdnzl-array (list &optional (base-type (make-type-from-name "System.Object"))) "Creates and returns a .NET array of base type BASE-TYPE \(a -CONTAINER or a string) and rank 1 with the elements from the Lisp list +CONTAINER, a string or a tree of strings) and rank 1 with the elements from the Lisp list LIST." - (when (stringp base-type) + (when (or (stringp base-type)(consp base-type)) (setq base-type (make-type-from-name (resolve-type-name base-type)))) (let* ((length (length list)) ;; this is equivalent to calling NEW (see import.lisp) @@ -104,7 +104,7 @@ integer. This is a destructive operatio (defun integer-to-enum (number type) "Converts the Lisp integer NUMBER to a .NET System.Enum object of type TYPE \(a string or a CONTAINER)." - (when (stringp type) + (when (or (stringp type)(consp type)) (setq type (make-type-from-name (resolve-type-name type)))) (cast [System.Enum.ToObject type number] type)) Only in rdnzl: arrays.lisp~ diff -urp rdnzl-0.11.2\container.lisp rdnzl\container.lisp --- rdnzl-0.11.2\container.lisp Sat Jan 26 23:28:30 2008 +++ rdnzl\container.lisp Wed Feb 13 00:42:37 2008 @@ -110,10 +110,12 @@ allowed." ((and (consp typespec) (eq (first typespec) 'or)) (rest typespec)) + ;; Generic types denoted by lists + ((consp typespec) (list typespec)) (t (error "Illegal typespec ~S in RDNZL-HANDLER-CASE" typespec))) collect `((or ,@(mapcar (lambda (typespec) - `(invoke (make-type-from-name (resolve-type-name ,typespec)) + `(invoke (make-type-from-name (resolve-type-name ',typespec)) "IsAssignableFrom" (invoke ,exception "GetType"))) typespec-list)) @@ -159,10 +161,21 @@ collected. NIL is returned if FORM retu (defun make-type-from-name (name) "Returns the .NET type with the name NAME - uses the static function -Type::GetType." - (wrap-with-container - (ffi-call-with-foreign-string* %make-type-from-name - name))) +Type::GetType. If NAME is a tree of strings, interpret this as a generic +type, use Type::GetType on each 'leaf' type and produce the type using +Type::MakeGenericType" + (if (stringp name) + (wrap-with-container + (ffi-call-with-foreign-string* %make-type-from-name + name)) + (let* ((types (mapcar #'make-type-from-name name)) + (base-type (car types)) + (parameter-types (cdr types))) + (invoke base-type "MakeGenericType" + (list-to-rdnzl-array + parameter-types "System.Type"))))) + + (defun get-object-as-string (container) "Get a string representation of the object denoted by CONTAINER. @@ -304,9 +317,20 @@ GET-INVOCATION-RESULT." ,args)))))) (defun make-type-from-assembly-and-name (assembly name) - "Returns the .NET type with the name NAME from a specific assembly." - (ffi-call-with-args %invoke-instance-member - assembly "GetType" (list name))) + "Returns the .NET type with the name NAME from a specific assembly. +If the type is passed type-arguments, assume it is a generic type, but +resolve the type-parameters normally." + (let* ((base-name (if (stringp name) name + (concatenate 'string (car name) + (format nil "`~d" (length (cdr name)))))) + (base-type + (ffi-call-with-args %invoke-instance-member + assembly "GetType" (list base-name)))) + (if (stringp name) base-type + (let ((parameter-types (mapcar #'make-type-from-name (mapcar #'resolve-type-name (rest name))))) + (invoke base-type "MakeGenericType" + (list-to-rdnzl-array + parameter-types "System.Type")))))) ;; generic functions and TYPECASE are avoided below to make delivered ;; images smaller @@ -316,11 +340,14 @@ GET-INVOCATION-RESULT." is a CONTAINER then the method is supposed to be an instance method of this object. If OBJECT is a string then the method is supposed to be a static method of the type named OBJECT which -will be looked up using System.Type::GetType. Otherwise, OBJECT -should be a two-element list where the first element is a +will be looked up using System.Type::GetType. If OBJECT is a tree +of strings, then the method should be a static method of the generic +type named OBJECT, with the rest-arguments being the parameters of the type. +Otherwise, OBJECT should be a pair where the first element is a CONTAINER representing an assembly and the second element is a -string denoting a static method \(which will be looked up in that -specific assembly). ARGS (either CONTAINER structures or Lisp +string (or tree of strings) denoting a type (possibly generic) \(which will be +looked up in that specific assembly), for which the +method-name is a static method . ARGS (either CONTAINER structures or Lisp objects which can be converted) are the arguments to this method." (let ((result @@ -329,14 +356,16 @@ method." object method-name args)) - ((stringp object) + ((or (stringp object) + (and (consp object) (stringp (car object)))) (ffi-call-with-args %invoke-static-member (make-type-from-name (resolve-type-name object)) method-name args)) ((and (consp object) (container-p (car object)) - (stringp (cdr object))) + (or (stringp (cdr object)) + (consp (cdr object)))) (ffi-call-with-args %invoke-static-member (make-type-from-assembly-and-name (car object) (cdr object)) method-name @@ -362,7 +391,7 @@ indexes to this property." object property-name args)) - ((stringp object) + ((or (stringp object)(consp object)) (ffi-call-with-args %get-static-property-value (make-type-from-name (resolve-type-name object)) property-name @@ -381,7 +410,7 @@ be converted) are the indexes to this pr object property-name (cons new-value args))) - ((stringp object) + ((or (stringp object)(consp object)) (ffi-call-with-args %set-static-property-value (make-type-from-name (resolve-type-name object)) property-name @@ -398,7 +427,7 @@ static field of the type named OBJECT." (ffi-call-with-foreign-string %get-instance-field-value field-name object)) - ((stringp object) + ((or (stringp object)(consp object)) (ffi-call-with-foreign-string %get-static-field-value field-name (make-type-from-name (resolve-type-name object)))) @@ -414,7 +443,7 @@ field is supposed to be a static field o field-name object new-value)) - ((stringp object) + ((or (stringp object)(consp object)) (ffi-call-with-foreign-string %set-static-field-value field-name (make-type-from-name (resolve-type-name object)) @@ -458,9 +487,12 @@ work with types loaded in a LoadFrom con (defun cast (container type) "Changes the type of the DotNetContainer object represented by -CONTAINER to TYPE \(a string or a CONTAINER). Returns CONTAINER." +CONTAINER to TYPE \(a string, tree of strings or a CONTAINER). Returns CONTAINER." (cond ((stringp type) (cast* container (resolve-type-name type))) + ((consp type) + (cast-to-type-object container + (make-type-from-name (resolve-type-name type)))) (t (cast-to-type-object container type)))) (defun copy-container (container) @@ -478,7 +510,14 @@ TYPE-NAME." (defun make-null-object (type-name) "Like MAKE-NULL-OBJECT* but resolves TYPE-NAME first." - (make-null-object* (resolve-type-name type-name))) + (if (stringp type-name) + (make-null-object* (resolve-type-name type-name)) + (make-null-object* + (property + (make-type-from-name + (resolve-type-name type-name)) + "AssemblyQualifiedName")))) + (defun build-delegate-type (type-name return-type arg-type-array) "Build a subtype of DelegateAdapter \(see C++ code) with the Only in rdnzl: container.lisp~ diff -urp rdnzl-0.11.2\import.lisp rdnzl\import.lisp --- rdnzl-0.11.2\import.lisp Sat Jan 26 23:28:30 2008 +++ rdnzl\import.lisp Tue Feb 12 01:42:14 2008 @@ -71,7 +71,7 @@ and/or CONTAINERs), i.e. by the correspo a string \(naming the type) or a CONTAINER \(representing the type). If TYPE is a delegate then the second argument to NEW must be a Lisp closure with a correspoding signature." - (cond ((stringp type) + (cond ((or (stringp type)(consp type)) (apply #'new (make-type-from-name (resolve-type-name type)) other-args)) Only in rdnzl: import.lisp~ diff -urp rdnzl-0.11.2\util.lisp rdnzl\util.lisp --- rdnzl-0.11.2\util.lisp Sat Jan 26 23:28:32 2008 +++ rdnzl\util.lisp Wed Feb 13 00:15:45 2008 @@ -142,14 +142,21 @@ prefixed when trying to resolve a type n "If NAME \(a string) names a type which has been previously imported via IMPORT-TYPE then return its assembly-qualified name. If a type named NAME can't be found directly then also try the `used' -namespaces." - (loop for namespace in (cons "" *used-namespaces*) - for full-name = (concatenate 'string namespace name) - for hashed-name = (gethash full-name *type-hash*) - when hashed-name - do (return (cond ((stringp hashed-name) hashed-name) - (t full-name))) - finally (return name))) +namespaces. If NAME is a tree of strings, interpret this as a +generic type and resolve each leaf as above, except that for the first +(base) type, `d-suffix giving the number of parameters is added automatically" + (if (stringp name) + (loop for namespace in (cons "" *used-namespaces*) + for full-name = (concatenate 'string namespace name) + for hashed-name = (gethash full-name *type-hash*) + when hashed-name + do (return (cond ((stringp hashed-name) hashed-name) + (t full-name))) + finally (return name)) + (let ((first-type-name + (concatenate 'string (car name) + (format nil "`~d" (length (rest name)))))) + (mapcar #'resolve-type-name (cons first-type-name (rest name)))))) (defun mangle-name (string) "Converts the string STRING into another string with case determined Only in rdnzl: util.lisp~