Skip to content

Commit 3289d7b

Browse files
committed
Various edits on ClrTypeSpec2, adding tests for ClrTypeSpec2. Revert to RT.classForName calling ClrTypeSpec so we can get an alpha out with the assembly loading changes only.
1 parent e1aa5b0 commit 3289d7b

File tree

8 files changed

+361
-236
lines changed

8 files changed

+361
-236
lines changed

Clojure/Clojure.Source/clojure/core_clr.clj

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -386,4 +386,16 @@
386386
[exp & body]
387387
(when (try (eval exp)
388388
(catch Exception _ false)) ;;; Throwable
389-
`(do ~@body)))
389+
`(do ~@body)))
390+
391+
(defn- add-type-alias
392+
([sym type] (add-type-alias sym type *ns*))
393+
([^clojure.lang.Symbol sym ^Type type ^clojure.lang.Namespace ns]
394+
;; TODO: check for symbol error: bad characters, overwriting built-ins, etc.
395+
(.importClass ns sym type)))
396+
397+
(defmacro alias-type
398+
{:added "1.12"}
399+
([sym type] `(#'add-type-alias '~sym ~type))
400+
([sym type ns] `(#'add-type-alias '~sym ~type ~ns)))
401+

Clojure/Clojure/CljCompiler/Compiler.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ public static class Compiler
4848

4949
internal static void RegisterDuplicateType(Type type)
5050
{
51-
_evalTypeMap[type.FullName] = type;
51+
_evalTypeMap[type.FullName] = type;
5252
}
5353

5454
internal static Type FindDuplicateType(string typename)

Clojure/Clojure/Lib/ClrTypeSpec.cs

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
using System;
22
using System.Collections.Generic;
3-
using System.Linq;
4-
using System.Text;
53
using System.Reflection;
64

75
namespace clojure.lang
@@ -20,7 +18,7 @@ namespace clojure.lang
2018
//
2119
// Copyright (C) 2010 Novell, Inc (http://www.novell.com)
2220

23-
class ClrArraySpec
21+
public class ClrArraySpec
2422
{
2523

2624
#region Data
@@ -33,10 +31,10 @@ class ClrArraySpec
3331
#region C-tors
3432

3533
internal ClrArraySpec(int dimensions, bool bound)
36-
{
37-
this._dimensions = dimensions;
38-
this._isBound = bound;
39-
}
34+
{
35+
this._dimensions = dimensions;
36+
this._isBound = bound;
37+
}
4038

4139
#endregion
4240

@@ -54,7 +52,7 @@ internal Type Resolve(Type type)
5452
#endregion
5553
}
5654

57-
class ClrTypeSpec
55+
public class ClrTypeSpec
5856
{
5957
#region Data
6058

@@ -101,7 +99,7 @@ static ClrTypeSpec Parse(string name, ref int p, bool isRecursive, bool allowAss
10199
int pos = p;
102100
int name_start;
103101
bool hasModifiers = false;
104-
ClrTypeSpec spec = new ClrTypeSpec();
102+
ClrTypeSpec spec = new();
105103

106104
SkipSpace(name, ref pos);
107105

@@ -123,8 +121,8 @@ static ClrTypeSpec Parse(string name, ref int p, bool isRecursive, bool allowAss
123121
{
124122
p = pos;
125123
return spec;
126-
}
127-
hasModifiers = true;
124+
}
125+
hasModifiers = true;
128126
break;
129127
case '&':
130128
case '*':
@@ -135,6 +133,9 @@ static ClrTypeSpec Parse(string name, ref int p, bool isRecursive, bool allowAss
135133
name_start = pos + 1;
136134
hasModifiers = true;
137135
break;
136+
case '\\':
137+
pos++;
138+
break;
138139
}
139140
if (hasModifiers)
140141
break;
@@ -186,7 +187,7 @@ static ClrTypeSpec Parse(string name, ref int p, bool isRecursive, bool allowAss
186187

187188
if (name[pos] != ',' && name[pos] != '*' && name[pos] != ']')
188189
{//generic args
189-
List<ClrTypeSpec> args = new List<ClrTypeSpec>();
190+
List<ClrTypeSpec> args = new();
190191
if (spec.IsArray)
191192
return null; // ArgumentException ("generic args after array spec", "typeName");
192193

Clojure/Clojure/Lib/ClrTypeSpec2.cs

Lines changed: 36 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using System;
1+
using clojure.lang.CljCompiler.Ast;
2+
using System;
23
using System.Collections.Generic;
34
using System.Linq;
45
using System.Reflection;
@@ -53,7 +54,7 @@ internal Type Resolve(Type type)
5354
#endregion
5455
}
5556

56-
class ClrTypeSpec2
57+
public class ClrTypeSpec2
5758
{
5859
#region Data
5960

@@ -76,9 +77,8 @@ public static Type GetTypeFromName(string name, Namespace ns = null)
7677
return null;
7778
return spec.Resolve(
7879
ns,
79-
assyName => Assembly.Load(assyName),
80-
//(assy, typeName) => assy == null ? RT.classForName(typeName) : assy.GetType(typeName)); <--- this goes into an infinite loop on a non-existent typename
81-
DefaultTypeResolver);
80+
name,
81+
assyName => Assembly.Load(assyName));
8282
}
8383

8484
#endregion
@@ -129,12 +129,15 @@ static ClrTypeSpec2 Parse(string name, ref int p, bool isRecursive, bool allowAs
129129
case '&':
130130
case '*':
131131
case '[':
132-
if (name[pos] != '[' && isRecursive)
132+
if (name[pos] != '[' && name[pos] != '<' && isRecursive)
133133
return null; // ArgumentException ("Generic argument can't be byref or pointer type", "typeName");
134134
spec.AddName(name.Substring(name_start, pos - name_start));
135135
name_start = pos + 1;
136136
hasModifiers = true;
137137
break;
138+
case '\\':
139+
pos++;
140+
break;
138141
}
139142
if (hasModifiers)
140143
break;
@@ -246,59 +249,6 @@ static ClrTypeSpec2 Parse(string name, ref int p, bool isRecursive, bool allowAs
246249

247250
break;
248251

249-
case '<':
250-
// This case is identical to `[` in the parts that correspond to looking for generic arguments.
251-
// It differs in that it does not devolve into array specification if not generic.
252-
// It also differs in that upon completion (seeing the matching '>') we need to amend the name to include backquote + count.
253-
254-
if (spec._isByRef)
255-
return null; // ArgumentException ("Byref qualifier must be the last one of a type", "typeName");
256-
++pos;
257-
if (pos >= name.Length)
258-
return null; // ArgumentException ("Invalid array/generic spec", "typeName");
259-
SkipSpace(name, ref pos);
260-
261-
if (name[pos] != ',' && name[pos] != '*' && name[pos] != '>')
262-
{//generic args
263-
List<ClrTypeSpec2> args = new();
264-
if (spec.IsArray)
265-
return null; // ArgumentException ("generic args after array spec", "typeName");
266-
267-
while (pos < name.Length)
268-
{
269-
SkipSpace(name, ref pos);
270-
bool aqn = name[pos] == '[';
271-
if (aqn)
272-
++pos; //skip '[' to the start of the type
273-
{
274-
ClrTypeSpec2 arg = Parse(name, ref pos, true, aqn);
275-
if (arg == null)
276-
return null; // bad generic arg
277-
args.Add(arg);
278-
}
279-
if (pos >= name.Length)
280-
return null; // ArgumentException ("Invalid generic arguments spec", "typeName");
281-
282-
if (name[pos] == '>')
283-
spec.AppendNameGenericCountSuffix(args.Count);
284-
break;
285-
if (name[pos] == ',')
286-
++pos; // skip ',' to the start of the next arg
287-
else
288-
return null; // ArgumentException ("Invalid generic arguments separator " + name [pos], "typeName")
289-
290-
}
291-
if (pos >= name.Length || name[pos] != ']')
292-
return null; // ArgumentException ("Error parsing generic params spec", "typeName");
293-
spec._genericParams = args;
294-
}
295-
else
296-
{
297-
return null; // ArgumentException("Error parsing generic params spec", "typeName");
298-
}
299-
300-
break;
301-
302252
case ']':
303253
if (isRecursive)
304254
{
@@ -376,8 +326,8 @@ void AddArray(ClrArraySpec2 array)
376326

377327
internal Type Resolve(
378328
Namespace ns,
379-
Func<AssemblyName, Assembly> assemblyResolver,
380-
Func<Assembly, string, Namespace, Type> typeResolver)
329+
string originalTypename,
330+
Func<AssemblyName, Assembly> assemblyResolver)
381331
{
382332
Assembly asm = null;
383333

@@ -392,8 +342,30 @@ internal Type Resolve(
392342
return null;
393343
}
394344

395-
Type type = typeResolver(asm, _name, ns);
396-
if (type == null)
345+
// if _name is same as originalTypename, then the parse is identical to what we started with.
346+
// Given that ClrTypeSpec2.GetTypeFromName is called from RT.classForName,
347+
// call RT.classForName when _name == originalTypename will set off an infinite recrusion.
348+
349+
Type type = null;
350+
351+
if (asm != null)
352+
type = asm.GetType(_name);
353+
else
354+
{
355+
type = HostExpr.maybeSpecialTag(Symbol.create(_name));
356+
357+
// check for aliases in the namespace
358+
if (type is null && ns is not null)
359+
{
360+
type = ns.GetMapping(Symbol.create(_name)) as Type;
361+
}
362+
363+
if (type is null && (!_name?.Equals(originalTypename) ?? false))
364+
type = RT.classForName(_name);
365+
}
366+
367+
if (type is null)
368+
// Cannot resolve _name
397369
return null;
398370

399371
if (_nested != null)
@@ -412,7 +384,7 @@ internal Type Resolve(
412384
Type[] args = new Type[_genericParams.Count];
413385
for (int i = 0; i < args.Length; ++i)
414386
{
415-
var tmp = _genericParams[i].Resolve(ns, assemblyResolver, typeResolver);
387+
var tmp = _genericParams[i].Resolve(ns, originalTypename, assemblyResolver);
416388
if (tmp == null)
417389
return null;
418390
args[i] = tmp;

0 commit comments

Comments
 (0)