diff src/clojure/contrib/import_static.clj @ 10:ef7dbbd6452c

added clojure source goodness
author Robert McIntyre <rlm@mit.edu>
date Sat, 21 Aug 2010 06:25:44 -0400
parents
children
line wrap: on
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/clojure/contrib/import_static.clj	Sat Aug 21 06:25:44 2010 -0400
     1.3 @@ -0,0 +1,63 @@
     1.4 +;;; import_static.clj -- import static Java methods/fields into Clojure
     1.5 +
     1.6 +;; by Stuart Sierra, http://stuartsierra.com/
     1.7 +;; June 1, 2008
     1.8 +
     1.9 +;; Copyright (c) Stuart Sierra, 2008. All rights reserved.  The use
    1.10 +;; and distribution terms for this software are covered by the Eclipse
    1.11 +;; Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
    1.12 +;; which can be found in the file epl-v10.html at the root of this
    1.13 +;; distribution.  By using this software in any fashion, you are
    1.14 +;; agreeing to be bound by the terms of this license.  You must not
    1.15 +;; remove this notice, or any other, from this software.
    1.16 +
    1.17 +
    1.18 +
    1.19 +(ns 
    1.20 +  ^{:author "Stuart Sierra",
    1.21 +     :doc "Import static Java methods/fields into Clojure"}
    1.22 +  clojure.contrib.import-static
    1.23 +            (:use clojure.set))
    1.24 +
    1.25 +(defmacro import-static
    1.26 +  "Imports the named static fields and/or static methods of the class
    1.27 +  as (private) symbols in the current namespace.
    1.28 +
    1.29 +  Example: 
    1.30 +      user=> (import-static java.lang.Math PI sqrt)
    1.31 +      nil
    1.32 +      user=> PI
    1.33 +      3.141592653589793
    1.34 +      user=> (sqrt 16)
    1.35 +      4.0
    1.36 +
    1.37 +  Note: The class name must be fully qualified, even if it has already
    1.38 +  been imported.  Static methods are defined as MACROS, not
    1.39 +  first-class fns."
    1.40 +  [class & fields-and-methods]
    1.41 +  (let [only (set (map str fields-and-methods))
    1.42 +        the-class (. Class forName (str class))
    1.43 +        static? (fn [x]
    1.44 +                    (. java.lang.reflect.Modifier
    1.45 +                       (isStatic (. x (getModifiers)))))
    1.46 +        statics (fn [array]
    1.47 +                    (set (map (memfn getName)
    1.48 +                              (filter static? array))))
    1.49 +        all-fields (statics (. the-class (getFields)))
    1.50 +        all-methods (statics (. the-class (getMethods)))
    1.51 +        fields-to-do (intersection all-fields only)
    1.52 +        methods-to-do (intersection all-methods only)
    1.53 +        make-sym (fn [string]
    1.54 +                     (with-meta (symbol string) {:private true}))
    1.55 +        import-field (fn [name]
    1.56 +                         (list 'def (make-sym name)
    1.57 +                               (list '. class (symbol name))))
    1.58 +        import-method (fn [name]
    1.59 +                          (list 'defmacro (make-sym name)
    1.60 +                                '[& args]
    1.61 +                                (list 'list ''. (list 'quote class)
    1.62 +                                      (list 'apply 'list
    1.63 +                                            (list 'quote (symbol name))
    1.64 +                                            'args))))]
    1.65 +    `(do ~@(map import-field fields-to-do)
    1.66 +         ~@(map import-method methods-to-do))))