diff --git a/src/clj/clojure/genclass.clj b/src/clj/clojure/genclass.clj index 710e58a1a3..afef85c8ef 100644 --- a/src/clj/clojure/genclass.clj +++ b/src/clj/clojure/genclass.clj @@ -101,15 +101,26 @@ 'char Character/TYPE 'chars (Class/forName "[C")}) -(defn- ^Class the-class [x] - (cond - (class? x) x - (contains? prim->class x) (prim->class x) - :else (let [strx (str x)] - (clojure.lang.RT/classForName - (if (some #{\. \[} strx) - strx - (str "java.lang." strx)))))) +(defn- the-array-class [sym] + (clojure.lang.RT/classForName + (let [cn (namespace sym)] + (clojure.lang.Compiler$HostExpr/buildArrayClassDescriptor + (if (or (clojure.lang.Compiler/primClass (symbol cn)) (some #{\.} cn)) + sym + (symbol (str "java.lang." cn) (name sym))))))) + +(defn- ^Class the-class [x] + (cond + (class? x) x + (symbol? x) (cond (contains? prim->class x) (prim->class x) + (clojure.lang.Compiler$HostExpr/looksLikeArrayClass x) + (the-array-class x) + :else (let [strx (str x)] + (clojure.lang.RT/classForName + (if (some #{\. \[} strx) + strx + (str "java.lang." strx))))) + :else (clojure.lang.RT/classForName x))) ;; someday this can be made codepoint aware (defn- valid-java-method-name diff --git a/src/jvm/clojure/lang/Compiler.java b/src/jvm/clojure/lang/Compiler.java index 6324456fa1..80c25e79e6 100644 --- a/src/jvm/clojure/lang/Compiler.java +++ b/src/jvm/clojure/lang/Compiler.java @@ -1124,10 +1124,11 @@ static Class tagToClass(Object tag) { throw new IllegalArgumentException("Unable to resolve classname: " + tag); } - public static Class maybeArrayClass(Symbol sym) { - if(sym.ns == null || !Util.isPosDigit(sym.name)) - return null; + public static boolean looksLikeArrayClass(Symbol sym) { + return sym.ns != null && Util.isPosDigit(sym.name); + } + public static String buildArrayClassDescriptor(Symbol sym) { int dim = sym.name.charAt(0) - '0'; Symbol componentClassName = Symbol.intern(null, sym.ns); Class componentClass = primClass(componentClassName); @@ -1137,7 +1138,7 @@ public static Class maybeArrayClass(Symbol sym) { if(componentClass == null) throw Util.sneakyThrow(new ClassNotFoundException("Unable to resolve component classname: " - + componentClassName)); + + componentClassName)); StringBuilder arrayDescriptor = new StringBuilder(); @@ -1149,7 +1150,14 @@ public static Class maybeArrayClass(Symbol sym) { : "L" + componentClass.getName() + ";"; arrayDescriptor.append(ccDescr); - return maybeClass(arrayDescriptor.toString(), true); + return arrayDescriptor.toString(); + } + + public static Class maybeArrayClass(Symbol sym) { + if(!looksLikeArrayClass(sym)) + return null; + + return maybeClass(buildArrayClassDescriptor(sym), true); } } @@ -9184,7 +9192,7 @@ static Class retType(Class tc, Class ret){ return tc; } - static Class primClass(Symbol sym){ + public static Class primClass(Symbol sym){ if(sym == null) return null; Class c = null; diff --git a/test/clojure/test_clojure/genclass.clj b/test/clojure/test_clojure/genclass.clj index 18e808dc11..48ad866365 100644 --- a/test/clojure/test_clojure/genclass.clj +++ b/test/clojure/test_clojure/genclass.clj @@ -149,3 +149,13 @@ (visitSource [source debug] (.append sourceFile source)))] (.accept classReader sourceVisitor 0) (is (= "examples.clj" (str sourceFile))))) + +(deftest array-descriptors->class + (are [descr c] (= (#'clojure.core/the-class descr) c) + "[Ljava.util.UUID;" java.util.UUID/1 + 'String java.lang.String + 'String/1 java.lang.String/1 + 'java.util.UUID java.util.UUID + 'java.util.UUID/2 java.util.UUID/2 + 'int/1 int/1 + 'boolean/9 boolean/9))
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: