Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
  • 13 commits
  • 12 files changed
  • 0 comments
  • 5 contributors
Jul 13, 2010
Stuart Halloway prepare for 1.2.0 beta1 9c01e1f
Jul 16, 2010
Rich Hickey switch to soft refs in DynamicClassLoader 27df859
Rich Hickey factor out cache clearing to Util helper 758672e
Rich Hickey use soft refs for keyword intern table ed89fd1
Jul 19, 2010
Stuart Halloway minor errata in changes.txt 43c7e04
Jul 27, 2010
Stuart Halloway Merge commit '43c7e04' into 1.2.x f27cb08
Fixes missing this arg on the reify and defprotocol docstrings #340
Signed-off-by: Stuart Halloway <stu@thinkrelevance.com>
bbc859d
David Powell read stdout and stderr in parallel (using futures)
Signed-off-by: Stuart Halloway <stu@thinkrelevance.com>
f314991
Stuart Halloway fix degenerate defrecords, #402
Signed-off-by: Stuart Halloway <stu@thinkrelevance.com>
9929b83
David Powell fixed extend-protocol doc
Signed-off-by: Stuart Halloway <stu@thinkrelevance.com>
973ea84
Ben Smith-Mannschott ♯413 parse-args defaults in-enc and out-enc to UTF-8, as required by sh
Previously parse-args was defaulting in-enc and out-enc to the
platform default charset. This contradicted the intent of sh, which is
to default to UTF-8 on all platforms.

This appears not to have been noticed because the unit tests were
still testing for the previous behavior of defaulting to platform
encoding.

(As it turns out the old behavior of using Charset/defaultCharset
would have been wrong on Mac OS X since it claims "Mac Roman" here
despite the fact that Mac OS X uses UTF-8 throughout, including in
Terminal.app, shell and file system.)

Signed-off-by: Stuart Halloway <stu@thinkrelevance.com>
a2c95ef
Jul 30, 2010
Stuart Halloway #407 use munge as cheap validity test for Java method names
Signed-off-by: Stuart Halloway <stu@thinkrelevance.com>
60d5927
Stuart Halloway prep for 1.2 RC1 6dec446
265  changes.txt
... ...
@@ -0,0 +1,265 @@
  1
+Changes to Clojure in Version 1.2
  2
+
  3
+= CONTENTS =
  4
+
  5
+ 0 Changes from beta1 to RC1
  6
+ 1 Deprecated and Removed Features
  7
+    1.1 metadata reader macro is now ^
  8
+ 2 New/Improved Features in clojure.core
  9
+    2.1 Protocols, Records, and Types
  10
+    2.2 Sequence Library
  11
+    2.3 Destructuring
  12
+    2.4 Case
  13
+    2.5 Duplicate Key Prevention
  14
+    2.6 Primitive Vectors
  15
+    2.7 Agent Error Handling
  16
+    2.8 Improved Ratio Support
  17
+    2.9 Macro Implicit Args
  18
+    2.10 Multimethod Enhancements
  19
+    2.11 Function Metadata (Alpha)
  20
+    2.12 Java Annotations
  21
+    2.13 Namespace Collision Warnings
  22
+ 3 New Namespaces
  23
+    3.1 clojure.java.io
  24
+    3.1 clojure.java.javadoc
  25
+    3.3 clojure.java.shell
  26
+    3.4 clojure.pprint
  27
+    3.5 clojure.repl
  28
+    3.6 clojure.string
  29
+ 4 Functions with Improved Performance
  30
+ 5 Bug Fixes
  31
+
  32
+= 0 Changes from beta1 to RC1 =
  33
+
  34
+  * switch to soft refs for class and keyword cache
  35
+  * update reify, defprotocol, extend-protocol docstrings (#340)
  36
+  * fix fieldless defrecord corner case (#402)
  37
+  * sh reads stdout and stderr in parallel
  38
+  * sh stdin, stdout default to UTF-8 (#413)
  39
+  * gen-class checks validity of method names (#407)
  40
+ 
  41
+= 1 Deprecated and Removed Features =
  42
+
  43
+== 1.1 metadata reader macro is now ^ ==
  44
+
  45
+^ is the metadata reader macro. The former syntax #^ is deprecated and
  46
+will be removed in a future version of Clojure.
  47
+
  48
+
  49
+= 2 New Features in clojure.core =
  50
+
  51
+== 2.1 Protocols, Records, Reify, and Types ==
  52
+
  53
+defprotocol provides polymorphism without type intrusion.
  54
+
  55
+defrecord, reify, and deftype provide datatypes. They support, in a
  56
+relatively clean manner, access to the highest-performance primitive
  57
+representation and polymorphism mechanisms of the host.
  58
+
  59
+See http://clojure.org/protocols and http://clojure.org/datatypes for
  60
+a more complete description.
  61
+
  62
+
  63
+== 2.2 Sequence Library ==
  64
+
  65
+The sequence library has several new functions in Clojure 1.2. The
  66
+notes in parentheses indicate differences from the similarly-named
  67
+functions in clojure-contrib.
  68
+
  69
+  * flatten - New
  70
+  * frequencies - New
  71
+  * group-by - New        (note: unsorted)
  72
+  * keep - New
  73
+  * keep-indexed - New    (preferred over contrib's indexed for perf)
  74
+  * map-indexed - New     (preferred over contrib's indexed for perf)
  75
+  * partition-all - New
  76
+  * partition-by - New 
  77
+  * rand-nth - New        (name indicates dependency on nth's perf)
  78
+  * range - Improved      (added zero arity)
  79
+  * reductions - New
  80
+  * repeatedly - Improved! (added "do n times" semantics)
  81
+  * shuffle - New
  82
+
  83
+
  84
+== 2.3 Destructuring Enhanced ==
  85
+
  86
+If you associatively destructure a seq, it will be poured into a map first:
  87
+
  88
+  (defn foo [& {:keys [a b c]}]
  89
+    [a b c])
  90
+
  91
+  (foo :c 3 :b 2)
  92
+  => [nil 2 3]
  93
+
  94
+
  95
+== 2.4 Case ==
  96
+
  97
+Case provides constant time dispatch on its clauses, which can be any
  98
+compile-time literal
  99
+
  100
+  (defn release-status
  101
+    [version]
  102
+    (case version
  103
+     (0.9 1.0 1.1) "History"
  104
+     1.2           "Right now"
  105
+     :sentient     "RSN"))
  106
+
  107
+
  108
+== 2.5 Duplicate Key Prevention ==
  109
+
  110
+Associative literals and their constructor functions hash-map and
  111
+hash-set now prevent duplicate keys:
  112
+
  113
+  #{1 1}
  114
+  => java.lang.IllegalArgumentException: Duplicate key: 1
  115
+
  116
+
  117
+== 2.6 Primitive Vectors ==
  118
+
  119
+vector-of creates a vector of unboxed Java primitives, which follows
  120
+the contract of Clojure vectors.
  121
+
  122
+
  123
+== 2.7 Agent Error Handling ==
  124
+
  125
+Agent error handling has been reworked in Clojure 1.2.
  126
+
  127
+  * agent-error - New
  128
+  * restart-agent - New
  129
+  * set-error-handler - New
  130
+  * error-handler - New
  131
+  * set-error-mode! - New
  132
+  * error-mode - New
  133
+  * await - improved docstring, explains failed agent semantics
  134
+  * agent-errors - DEPRECATED
  135
+  * clear-agent-errors - DEPRECATED
  136
+
  137
+
  138
+== 2.8 Improved Ratio Support ==
  139
+
  140
+  * numerator - New
  141
+  * denominator - New
  142
+  * bigint - Enhanced, now ratio aware
  143
+
  144
+
  145
+== 2.9 Macro Implicit Args ==
  146
+
  147
+Macros now have access to implicit arguments:
  148
+ 
  149
+  * &form - the macro form
  150
+  * &env  - the local bindings
  151
+
  152
+
  153
+== 2.10 Multimethod Enhancements ==
  154
+
  155
+Multimethods have been enhanced to improve interactive development:
  156
+ 
  157
+  * remove-all-methods - New
  158
+  * defmulti - Enhanced to have defonce semantics
  159
+
  160
+
  161
+== 2.11 Function Metadata ==
  162
+
  163
+Clojure functions can now have metadata. Please treat this capability
  164
+as alpha and subject to possible change or removal in a future version
  165
+of Clojure.
  166
+
  167
+
  168
+== 2.12 Java Annotations ==
  169
+
  170
+Java Annotations can be added simply by making a Java annotation
  171
+class a key in a Clojure metadata map:
  172
+
  173
+  ;; Name is deprecated
  174
+  (defrecord ^{Deprecated true} Name [first last])
  175
+
  176
+Please use Java annotations for interop purposes only. 
  177
+
  178
+== 2.13 Namespace Collision Warnings ==
  179
+
  180
+If a namespace defines a Var whose name collides with a name in the
  181
+clojure.core namespace, you will see a warning but the definition will
  182
+be allowed to proceed. This facilitates promoting useful functions
  183
+into clojure.core without causing a breaking change.
  184
+
  185
+Please track down and fix these warnings, as matching names do not
  186
+always imply matching semantics!
  187
+
  188
+
  189
+= 3 New Namespaces =
  190
+
  191
+Complete documentation for all namespaces is in the source and API
  192
+docs: http://clojure.github.com/clojure/
  193
+
  194
+
  195
+== 3.1 clojure.java.io ==
  196
+
  197
+Java I/O libraries distilled from the duck-streams and io namespaces
  198
+in clojure-contrib.
  199
+
  200
+
  201
+== 3.2 clojure.java.javadoc ==
  202
+
  203
+Launch a Javadoc browser from the REPL, promoted from the javadoc and
  204
+repl-util namespace in clojure-contrib.
  205
+
  206
+
  207
+== 3.3 clojure.java.shell ==
  208
+
  209
+Utilities for launching a subprocess, promoted from shell-out
  210
+namespace in clojure-contrib.
  211
+
  212
+
  213
+== 3.4 clojure.pprint ==
  214
+
  215
+Pretty-printer for Clojure, promoted from pprint in clojure-contrib.
  216
+
  217
+
  218
+== 3.5 clojure.repl ==
  219
+
  220
+Utilities for a more pleasant REPL experience, promoted from the
  221
+repl-utils and ns-utils namespaces in clojure-contrib.
  222
+
  223
+
  224
+== 3.6 clojure.string ==
  225
+
  226
+String utilities promoted from the str-utils, str-utils2, str-utils3,
  227
+and string namespaces in clojure-contrib.
  228
+
  229
+
  230
+= 4 Performance Enhancements =
  231
+
  232
+Many functions have improved performance in Clojure 1.2:
  233
+    
  234
+  aget
  235
+  array-map
  236
+  aset
  237
+  bit-shift-left
  238
+  bit-shift-right
  239
+  boolean
  240
+  byte
  241
+  count
  242
+  double
  243
+  false?
  244
+  float
  245
+  future-call
  246
+  get
  247
+  into
  248
+  keyword
  249
+  line-seq
  250
+  long
  251
+  nil?
  252
+  nth
  253
+  promise
  254
+  re-seq
  255
+  reduce
  256
+  resultset-seq
  257
+  set
  258
+  short
  259
+  true?
  260
+  vector
  261
+   
  262
+= 5 Bug Fixes = 
  263
+
  264
+Please see the complete list at 
  265
+https://www.assembla.com/spaces/ticket_reports/show/13167?space_id=clojure.
60  src/clj/clojure/core_deftype.clj
@@ -70,11 +70,11 @@
70 70
   or more method bodies:
71 71
 
72 72
   protocol-or-interface-or-Object
73  
-  (methodName [args*] body)*
  73
+  (methodName [args+] body)*
74 74
 
75 75
   Methods should be supplied for all methods of the desired
76 76
   protocol(s) and interface(s). You can also define overrides for
77  
-  methods of Object. Note that a parameter must be supplied to
  77
+  methods of Object. Note that the first parameter must be supplied to
78 78
   correspond to the target object ('this' in Java parlance). Thus
79 79
   methods for interfaces will take one more argument than do the
80 80
   interface declarations.  Note also that recur calls to the method
@@ -97,12 +97,12 @@
97 97
   
98 98
   (str (let [f \"foo\"] 
99 99
        (reify Object 
100  
-         (toString [] f))))
  100
+         (toString [this] f))))
101 101
   == \"foo\"
102 102
 
103 103
   (seq (let [f \"foo\"] 
104 104
        (reify clojure.lang.Seqable 
105  
-         (seq [] (seq f)))))
  105
+         (seq [this] (seq f)))))
106 106
   == (\\f \\o \\o))"
107 107
   {:added "1.2"} 
108 108
   [& opts+specs]
@@ -195,8 +195,8 @@
195 195
                    `(entryAt [this# k#] (let [v# (.valAt this# k# this#)]
196 196
                                             (when-not (identical? this# v#)
197 197
                                               (clojure.lang.MapEntry. k# v#))))
198  
-                   `(seq [this#] (concat [~@(map #(list `new `clojure.lang.MapEntry (keyword %) %) base-fields)] 
199  
-                                          ~'__extmap))
  198
+                   `(seq [this#] (seq (concat [~@(map #(list `new `clojure.lang.MapEntry (keyword %) %) base-fields)] 
  199
+                                              ~'__extmap)))
200 200
                    `(assoc [this# k# ~gs]
201 201
                      (condp identical? k#
202 202
                        ~@(mapcat (fn [fld]
@@ -212,7 +212,7 @@
212 212
                  (conj m
213 213
                        `(size [this#] (.count this#))
214 214
                        `(isEmpty [this#] (= 0 (.count this#)))
215  
-                       `(containsValue [this# v#] (-> this# vals (.contains v#)))
  215
+                       `(containsValue [this# v#] (boolean (some #{v#} (vals this#))))
216 216
                        `(get [this# k#] (.valAt this# k#))
217 217
                        `(put [this# k# v#] (throw (UnsupportedOperationException.)))
218 218
                        `(remove [this# k#] (throw (UnsupportedOperationException.)))
@@ -581,18 +581,18 @@
581 581
     \"A doc string for AProtocol abstraction\"
582 582
 
583 583
   ;method signatures
584  
-    (bar [a b] \"bar docs\")
585  
-    (baz [a] [a b] [a b c] \"baz docs\"))
  584
+    (bar [this a b] \"bar docs\")
  585
+    (baz [this a] [this a b] [this a b c] \"baz docs\"))
586 586
 
587 587
   No implementations are provided. Docs can be specified for the
588 588
   protocol overall and for each method. The above yields a set of
589 589
   polymorphic functions and a protocol object. All are
590 590
   namespace-qualified by the ns enclosing the definition The resulting
591  
-  functions dispatch on the type of their first argument, and thus
592  
-  must have at least one argument. defprotocol is dynamic, has no
593  
-  special compile-time effect, and defines no new types or classes
594  
-  Implementations of the protocol methods can be provided using
595  
-  extend.
  591
+  functions dispatch on the type of their first argument, which is
  592
+  required and corresponds to the implicit target object ('this' in 
  593
+  Java parlance). defprotocol is dynamic, has no special compile-time 
  594
+  effect, and defines no new types or classes. Implementations of 
  595
+  the protocol methods can be provided using extend.
596 596
 
597 597
   defprotocol will automatically generate a corresponding interface,
598 598
   with the same name as the protocol, i.e. given a protocol:
@@ -604,23 +604,25 @@
604 604
   reify, as they support the protocol directly:
605 605
 
606 606
   (defprotocol P 
607  
-    (foo [x]) 
608  
-    (bar-me [x] [x y]))
  607
+    (foo [this]) 
  608
+    (bar-me [this] [this y]))
609 609
 
610 610
   (deftype Foo [a b c] 
611 611
    P
612  
-    (foo [] a)
613  
-    (bar-me [] b)
614  
-    (bar-me [y] (+ c y)))
  612
+    (foo [this] a)
  613
+    (bar-me [this] b)
  614
+    (bar-me [this y] (+ c y)))
615 615
   
616  
-  (bar-me (Foo 1 2 3) 42)
  616
+  (bar-me (Foo. 1 2 3) 42)
  617
+  => 45
617 618
 
618 619
   (foo 
619 620
     (let [x 42]
620 621
       (reify P 
621  
-        (foo [] 17)
622  
-        (bar-me [] x)
623  
-        (bar-me [y] x))))"
  622
+        (foo [this] 17)
  623
+        (bar-me [this] x)
  624
+        (bar-me [this y] x))))
  625
+  => 17"
624 626
   {:added "1.2"} 
625 627
   [name & opts+sigs]
626 628
   (emit-protocol name opts+sigs))
@@ -729,13 +731,13 @@
729 731
   "Useful when you want to provide several implementations of the same
730 732
   protocol all at once. Takes a single protocol and the implementation
731 733
   of that protocol for one or more types. Expands into calls to
732  
-  extend-type and extend-class:
  734
+  extend-type:
733 735
 
734 736
   (extend-protocol Protocol
735  
-    ::AType
  737
+    AType
736 738
       (foo [x] ...)
737 739
       (bar [x y] ...)
738  
-    ::BType
  740
+    BType
739 741
       (foo [x] ...)
740 742
       (bar [x y] ...)
741 743
     AClass
@@ -748,13 +750,13 @@
748 750
   expands into:
749 751
 
750 752
   (do
751  
-   (clojure.core/extend-type ::AType Protocol 
  753
+   (clojure.core/extend-type AType Protocol 
752 754
      (foo [x] ...) 
753 755
      (bar [x y] ...))
754  
-   (clojure.core/extend-type ::BType Protocol 
  756
+   (clojure.core/extend-type BType Protocol 
755 757
      (foo [x] ...) 
756 758
      (bar [x y] ...))
757  
-   (clojure.core/extend-class AClass Protocol 
  759
+   (clojure.core/extend-type AClass Protocol 
758 760
      (foo [x] ...) 
759 761
      (bar [x y] ...))
760 762
    (clojure.core/extend-type nil Protocol 
11  src/clj/clojure/genclass.clj
@@ -90,7 +90,18 @@
90 90
               strx
91 91
               (str "java.lang." strx))))))
92 92
 
  93
+;; someday this can be made codepoint aware
  94
+(defn- valid-java-method-name
  95
+  [^String s]
  96
+  (= s (clojure.lang.Compiler/munge s)))
  97
+
  98
+(defn- validate-generate-class-options
  99
+  [{:keys [methods]}]
  100
+  (let [[mname] (remove valid-java-method-name (map (comp str first) methods))]
  101
+    (when mname (throw (IllegalArgumentException. (str "Not a valid method name: " mname))))))
  102
+
93 103
 (defn- generate-class [options-map]
  104
+  (validate-generate-class-options options-map)
94 105
   (let [default-options {:prefix "-" :load-impl-ns true :impl-ns (ns-name *ns*)}
95 106
         {:keys [name extends implements constructors methods main factory state init exposes 
96 107
                 exposes-methods prefix load-impl-ns impl-ns post-init]} 
8  src/clj/clojure/java/shell.clj
@@ -44,7 +44,7 @@ collecting its stdout"}
44 44
 
45 45
 (defn- parse-args
46 46
   [args]
47  
-  (let [default-encoding (.name (Charset/defaultCharset))
  47
+  (let [default-encoding "UTF-8" ;; see sh doc string
48 48
         default-opts {:out-enc default-encoding :in-enc default-encoding :dir *sh-dir* :env *sh-env*}
49 49
         [cmd opts] (split-with string? args)]
50 50
     [cmd (merge default-opts (apply hash-map opts))]))
@@ -124,10 +124,10 @@ collecting its stdout"}
124 124
       (.close (.getOutputStream proc)))
125 125
     (with-open [stdout (.getInputStream proc)
126 126
                 stderr (.getErrorStream proc)]
127  
-      (let [out (stream-to-enc stdout out-enc)
128  
-            err (stream-to-string stderr)
  127
+      (let [out (future (stream-to-enc stdout out-enc))
  128
+            err (future (stream-to-string stderr))
129 129
             exit-code (.waitFor proc)]
130  
-        {:exit exit-code :out out :err err}))))
  130
+        {:exit exit-code :out @out :err @err}))))
131 131
 
132 132
 (comment
133 133
 
4  src/clj/clojure/version.properties
... ...
@@ -1,5 +1,5 @@
1 1
 clojure.version.major=1
2 2
 clojure.version.minor=2
3 3
 clojure.version.incremental=0
4  
-clojure.version.qualifier=master
5  
-clojure.version.interim=true
  4
+clojure.version.qualifier=RC1
  5
+clojure.version.interim=false
23  src/jvm/clojure/lang/DynamicClassLoader.java
@@ -14,17 +14,16 @@
14 14
 
15 15
 import java.util.HashMap;
16 16
 import java.util.Map;
17  
-import java.util.Arrays;
18 17
 import java.util.concurrent.ConcurrentHashMap;
19 18
 import java.net.URLClassLoader;
20 19
 import java.net.URL;
21  
-import java.lang.ref.WeakReference;
22 20
 import java.lang.ref.ReferenceQueue;
  21
+import java.lang.ref.SoftReference;
23 22
 
24 23
 public class DynamicClassLoader extends URLClassLoader{
25 24
 HashMap<Integer, Object[]> constantVals = new HashMap<Integer, Object[]>();
26  
-static ConcurrentHashMap<String, WeakReference<Class> >classCache =
27  
-        new ConcurrentHashMap<String, WeakReference<Class> >();
  25
+static ConcurrentHashMap<String, SoftReference<Class>>classCache =
  26
+        new ConcurrentHashMap<String, SoftReference<Class> >();
28 27
 
29 28
 static final URL[] EMPTY_URLS = new URL[]{};
30 29
 
@@ -42,24 +41,14 @@ public DynamicClassLoader(ClassLoader parent){
42 41
 }
43 42
 
44 43
 public Class defineClass(String name, byte[] bytes, Object srcForm){
  44
+	Util.clearCache(rq, classCache);
45 45
 	Class c = defineClass(name, bytes, 0, bytes.length);
46  
-    classCache.put(name, new WeakReference(c,rq));
47  
-	//cleanup any dead entries
48  
-	if(rq.poll() != null)
49  
-		{
50  
-		while(rq.poll() != null)
51  
-			;
52  
-		for(Map.Entry<String,WeakReference<Class>> e : classCache.entrySet())
53  
-			{
54  
-			if(e.getValue().get() == null)
55  
-				classCache.remove(e.getKey(), e.getValue());
56  
-			}
57  
-		}
  46
+    classCache.put(name, new SoftReference(c,rq));
58 47
     return c;
59 48
 }
60 49
 
61 50
 protected Class<?> findClass(String name) throws ClassNotFoundException{
62  
-    WeakReference<Class> cr = classCache.get(name);
  51
+    SoftReference<Class> cr = classCache.get(name);
63 52
 	if(cr != null)
64 53
 		{
65 54
 		Class c = cr.get();
16  src/jvm/clojure/lang/Keyword.java
@@ -15,18 +15,28 @@
15 15
 import java.io.ObjectStreamException;
16 16
 import java.io.Serializable;
17 17
 import java.util.concurrent.ConcurrentHashMap;
  18
+import java.lang.ref.ReferenceQueue;
  19
+import java.lang.ref.SoftReference;
18 20
 
19 21
 
20 22
 public final class Keyword implements IFn, Comparable, Named, Serializable {
21 23
 
22  
-private static ConcurrentHashMap<Symbol, Keyword> table = new ConcurrentHashMap();
  24
+private static ConcurrentHashMap<Symbol, SoftReference<Keyword>> table = new ConcurrentHashMap();
  25
+static final ReferenceQueue rq = new ReferenceQueue();
23 26
 public final Symbol sym;
24 27
 final int hash;
25 28
 
26 29
 public static Keyword intern(Symbol sym){
  30
+	Util.clearCache(rq, table);
27 31
 	Keyword k = new Keyword(sym);
28  
-	Keyword existingk = table.putIfAbsent(sym, k);
29  
-	return existingk == null ? k : existingk;
  32
+	SoftReference<Keyword> existingRef = table.putIfAbsent(sym, new SoftReference<Keyword>(k,rq));
  33
+	if(existingRef == null)
  34
+		return k;
  35
+	Keyword existingk = existingRef.get();
  36
+	if(existingk != null)
  37
+		return existingk;
  38
+	//entry died in the interim, do over
  39
+	return intern(sym);
30 40
 }
31 41
 
32 42
 public static Keyword intern(String ns, String name){
18  src/jvm/clojure/lang/Util.java
@@ -13,6 +13,11 @@
13 13
 package clojure.lang;
14 14
 
15 15
 import java.math.BigInteger;
  16
+import java.util.Map;
  17
+import java.util.concurrent.ConcurrentHashMap;
  18
+import java.lang.ref.SoftReference;
  19
+import java.lang.ref.ReferenceQueue;
  20
+import java.lang.ref.Reference;
16 21
 
17 22
 public class Util{
18 23
 static public boolean equiv(Object k1, Object k2){
@@ -89,4 +94,17 @@ static public ISeq ret1(ISeq ret, Object nil){
89 94
 		return ret;
90 95
 }
91 96
 
  97
+static public <K,V> void clearCache(ReferenceQueue rq, ConcurrentHashMap<K, SoftReference<V>> cache){
  98
+		//cleanup any dead entries
  99
+	if(rq.poll() != null)
  100
+		{
  101
+		while(rq.poll() != null)
  102
+			;
  103
+		for(Map.Entry<K, SoftReference<V>> e : cache.entrySet())
  104
+			{
  105
+			if(e.getValue().get() == null)
  106
+				cache.remove(e.getKey(), e.getValue());
  107
+			}
  108
+		}
  109
+}
92 110
 }
17  test/clojure/test_clojure/genclass.clj
@@ -9,7 +9,7 @@
9 9
 (ns ^{:doc "Tests for clojure.core/gen-class"
10 10
       :author "Stuart Halloway, Daniel Solano Gómez"}
11 11
   clojure.test-clojure.genclass
12  
-  (:use clojure.test)
  12
+  (:use clojure.test clojure.test-clojure.helpers)
13 13
   (:import [clojure.test_clojure.genclass.examples ExampleClass
14 14
                                                    ExampleAnnotationClass]
15 15
            [java.lang.annotation ElementType
@@ -17,17 +17,6 @@
17 17
                                  RetentionPolicy
18 18
                                  Target]))
19 19
 
20  
-;; pull this up to a suite-wide helper if you find other tests need it!
21  
-(defn get-field
22  
-  "Access to private or protected field.  field-name is a symbol or
23  
-  keyword."
24  
-  ([klass field-name]
25  
-     (get-field klass field-name nil))
26  
-  ([klass field-name inst]
27  
-     (-> klass (.getDeclaredField (name field-name))
28  
-         (doto (.setAccessible true))
29  
-         (.get inst))))
30  
-
31 20
 (deftest arg-support
32 21
   (let [example (ExampleClass.)
33 22
         o (Object.)]
@@ -70,3 +59,7 @@
70 59
             (let [target (aget first-param-annots 1)]
71 60
               (is (instance? Target target))
72 61
               (is (= [ElementType/TYPE ElementType/PARAMETER] (seq (.value target)))))))))))
  62
+
  63
+(deftest genclass-option-validation
  64
+  (is (fails-with-cause? IllegalArgumentException #"Not a valid method name: has-hyphen"
  65
+        (@#'clojure.core/validate-generate-class-options {:methods '[[fine [] void] [has-hyphen [] void]]}))))
12  test/clojure/test_clojure/helpers.clj
@@ -49,3 +49,15 @@
49 49
        (report {:type :fail, :message ~msg,
50 50
                 :expected '~form, :actual t#})))))
51 51
 
  52
+
  53
+(defn get-field
  54
+  "Access to private or protected field.  field-name is a symbol or
  55
+  keyword."
  56
+  ([klass field-name]
  57
+     (get-field klass field-name nil))
  58
+  ([klass field-name inst]
  59
+     (-> klass (.getDeclaredField (name field-name))
  60
+         (doto (.setAccessible true))
  61
+         (.get inst))))
  62
+
  63
+
10  test/clojure/test_clojure/java/shell.clj
@@ -12,13 +12,15 @@
12 12
   (:import (java.io File)))
13 13
 
14 14
 (def platform-enc (.name (java.nio.charset.Charset/defaultCharset)))
  15
+(def default-enc "UTF-8")
15 16
 
16 17
 (deftest test-parse-args
17 18
   (are [x y] (= x y)
18  
-       [[] {:in-enc platform-enc :out-enc platform-enc :dir nil :env nil}] (#'sh/parse-args [])
19  
-       [["ls"] {:in-enc platform-enc :out-enc platform-enc :dir nil :env nil}] (#'sh/parse-args ["ls"])
20  
-       [["ls" "-l"] {:in-enc platform-enc :out-enc platform-enc :dir nil :env nil}] (#'sh/parse-args ["ls" "-l"])
21  
-       [["ls"] {:in-enc platform-enc :out-enc "ISO-8859-1" :dir nil :env nil}] (#'sh/parse-args ["ls" :out-enc "ISO-8859-1"])))
  19
+       [[] {:in-enc default-enc :out-enc default-enc :dir nil :env nil}] (#'sh/parse-args [])
  20
+       [["ls"] {:in-enc default-enc :out-enc default-enc :dir nil :env nil}] (#'sh/parse-args ["ls"])
  21
+       [["ls" "-l"] {:in-enc default-enc :out-enc default-enc :dir nil :env nil}] (#'sh/parse-args ["ls" "-l"])
  22
+       [["ls"] {:in-enc default-enc :out-enc "ISO-8859-1" :dir nil :env nil}] (#'sh/parse-args ["ls" :out-enc "ISO-8859-1"])
  23
+       [[] {:in-enc platform-enc :out-enc platform-enc :dir nil :env nil}] (#'sh/parse-args [:in-enc platform-enc :out-enc platform-enc])))
22 24
   
23 25
 (deftest test-with-sh-dir
24 26
   (are [x y] (= x y)
5  test/clojure/test_clojure/protocols.clj
@@ -192,6 +192,11 @@
192 192
     (is (= {:foo 1 :b 2} (set/rename-keys rec {:a :foo})))
193 193
     (is (= {:a 11 :b 2 :c 10} (merge-with + rec {:a 10 :c 10})))))
194 194
 
  195
+(deftest degenerate-defrecord-test
  196
+  (let [empty (EmptyRecord.)]
  197
+    (is (nil? (seq empty)))
  198
+    (is (not (.containsValue empty :a)))))
  199
+
195 200
 (deftest defrecord-interfaces-test
196 201
   (testing "java.util.Map"
197 202
     (let [rec (r 1 2)]

No commit comments for this range

Something went wrong with that request. Please try again.