Skip to content

Commit 641933e

Browse files
foguspuredanger
authored andcommitted
CLJ-2888: Adding support for array symbols to gen-class. Retains existing gen-class constraints around unqualified symbols defaulting to java.lang package qualification.
1 parent 6a3e0f0 commit 641933e

3 files changed

Lines changed: 44 additions & 15 deletions

File tree

src/clj/clojure/genclass.clj

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -101,15 +101,26 @@
101101
'char Character/TYPE
102102
'chars (Class/forName "[C")})
103103

104-
(defn- ^Class the-class [x]
105-
(cond
106-
(class? x) x
107-
(contains? prim->class x) (prim->class x)
108-
:else (let [strx (str x)]
109-
(clojure.lang.RT/classForName
110-
(if (some #{\. \[} strx)
111-
strx
112-
(str "java.lang." strx))))))
104+
(defn- the-array-class [sym]
105+
(clojure.lang.RT/classForName
106+
(let [cn (namespace sym)]
107+
(clojure.lang.Compiler$HostExpr/buildArrayClassDescriptor
108+
(if (or (clojure.lang.Compiler/primClass (symbol cn)) (some #{\.} cn))
109+
sym
110+
(symbol (str "java.lang." cn) (name sym)))))))
111+
112+
(defn- ^Class the-class [x]
113+
(cond
114+
(class? x) x
115+
(symbol? x) (cond (contains? prim->class x) (prim->class x)
116+
(clojure.lang.Compiler$HostExpr/looksLikeArrayClass x)
117+
(the-array-class x)
118+
:else (let [strx (str x)]
119+
(clojure.lang.RT/classForName
120+
(if (some #{\. \[} strx)
121+
strx
122+
(str "java.lang." strx)))))
123+
:else (clojure.lang.RT/classForName x)))
113124

114125
;; someday this can be made codepoint aware
115126
(defn- valid-java-method-name

src/jvm/clojure/lang/Compiler.java

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1124,10 +1124,11 @@ static Class tagToClass(Object tag) {
11241124
throw new IllegalArgumentException("Unable to resolve classname: " + tag);
11251125
}
11261126

1127-
public static Class maybeArrayClass(Symbol sym) {
1128-
if(sym.ns == null || !Util.isPosDigit(sym.name))
1129-
return null;
1127+
public static boolean looksLikeArrayClass(Symbol sym) {
1128+
return sym.ns != null && Util.isPosDigit(sym.name);
1129+
}
11301130

1131+
public static String buildArrayClassDescriptor(Symbol sym) {
11311132
int dim = sym.name.charAt(0) - '0';
11321133
Symbol componentClassName = Symbol.intern(null, sym.ns);
11331134
Class componentClass = primClass(componentClassName);
@@ -1137,7 +1138,7 @@ public static Class maybeArrayClass(Symbol sym) {
11371138

11381139
if(componentClass == null)
11391140
throw Util.sneakyThrow(new ClassNotFoundException("Unable to resolve component classname: "
1140-
+ componentClassName));
1141+
+ componentClassName));
11411142

11421143
StringBuilder arrayDescriptor = new StringBuilder();
11431144

@@ -1149,7 +1150,14 @@ public static Class maybeArrayClass(Symbol sym) {
11491150
: "L" + componentClass.getName() + ";";
11501151

11511152
arrayDescriptor.append(ccDescr);
1152-
return maybeClass(arrayDescriptor.toString(), true);
1153+
return arrayDescriptor.toString();
1154+
}
1155+
1156+
public static Class maybeArrayClass(Symbol sym) {
1157+
if(!looksLikeArrayClass(sym))
1158+
return null;
1159+
1160+
return maybeClass(buildArrayClassDescriptor(sym), true);
11531161
}
11541162
}
11551163

@@ -9222,7 +9230,7 @@ static Class retType(Class tc, Class ret){
92229230
return tc;
92239231
}
92249232

9225-
static Class primClass(Symbol sym){
9233+
public static Class primClass(Symbol sym){
92269234
if(sym == null)
92279235
return null;
92289236
Class c = null;

test/clojure/test_clojure/genclass.clj

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,3 +149,13 @@
149149
(visitSource [source debug] (.append sourceFile source)))]
150150
(.accept classReader sourceVisitor 0)
151151
(is (= "examples.clj" (str sourceFile)))))
152+
153+
(deftest array-descriptors->class
154+
(are [descr c] (= (#'clojure.core/the-class descr) c)
155+
"[Ljava.util.UUID;" java.util.UUID/1
156+
'String java.lang.String
157+
'String/1 java.lang.String/1
158+
'java.util.UUID java.util.UUID
159+
'java.util.UUID/2 java.util.UUID/2
160+
'int/1 int/1
161+
'boolean/9 boolean/9))

0 commit comments

Comments
 (0)