Skip to content

Commit 8027c40

Browse files
committed
Refactor and optimize source code
1 parent 696031d commit 8027c40

16 files changed

+152
-19
lines changed

JSchema/RelogicLabs/JSchema/Functions/CoreFunctions1.cs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,12 @@
11
using RelogicLabs.JSchema.Exceptions;
22
using RelogicLabs.JSchema.Message;
3-
using RelogicLabs.JSchema.Tree;
43
using RelogicLabs.JSchema.Nodes;
54
using static RelogicLabs.JSchema.Message.ErrorCode;
65

76
namespace RelogicLabs.JSchema.Functions;
87

98
public sealed partial class CoreFunctions : FunctionProvider
109
{
11-
public CoreFunctions(RuntimeContext runtime) : base(runtime) { }
12-
1310
public bool Length(JString target, JInteger length)
1411
{
1512
var _length = target.Value.Length;

JSchema/RelogicLabs/JSchema/Functions/CoreFunctions4.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
using RelogicLabs.JSchema.Exceptions;
22
using RelogicLabs.JSchema.Message;
3-
using RelogicLabs.JSchema.Time;
43
using RelogicLabs.JSchema.Nodes;
4+
using RelogicLabs.JSchema.Time;
55
using static RelogicLabs.JSchema.Message.ErrorCode;
66
using static RelogicLabs.JSchema.Time.DateTimeType;
77

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
using RelogicLabs.JSchema.Tree;
2+
3+
namespace RelogicLabs.JSchema.Functions;
4+
5+
internal static class CoreLibrary
6+
{
7+
private static readonly FunctionMap _Functions = FunctionLoader.Load(typeof(CoreFunctions));
8+
9+
public static List<IEFunction>? GetFunctions(string key)
10+
=> _Functions.TryGetValue(key);
11+
}

JSchema/RelogicLabs/JSchema/Functions/DateTimeAgent.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
using RelogicLabs.JSchema.Exceptions;
22
using RelogicLabs.JSchema.Message;
3-
using RelogicLabs.JSchema.Time;
43
using RelogicLabs.JSchema.Nodes;
4+
using RelogicLabs.JSchema.Time;
55

66
namespace RelogicLabs.JSchema.Functions;
77

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
using RelogicLabs.JSchema.Nodes;
2+
using RelogicLabs.JSchema.Script;
3+
using RelogicLabs.JSchema.Tree;
4+
using RelogicLabs.JSchema.Utilities;
5+
using static RelogicLabs.JSchema.Script.IRFunction;
6+
using static RelogicLabs.JSchema.Tree.IEFunction;
7+
8+
namespace RelogicLabs.JSchema.Functions;
9+
10+
internal static class FunctionId
11+
{
12+
private const char EscapedPrefix = '_';
13+
14+
public static string Generate(JFunction caller, bool variadic = false)
15+
=> $"{caller.Name}#{(variadic ? VariadicArity : caller.Arguments.Count + 1)}";
16+
17+
public static string Generate(IEFunction function)
18+
=> $"{ConstraintPrefix}{function.Name.TrimStart(EscapedPrefix)
19+
.Uncapitalize()}#{function.Arity}";
20+
21+
public static string Generate(string baseName, GParameter[] parameters, bool constraint)
22+
{
23+
var arity = HasVariadic(parameters) ? VariadicArity : parameters.Length;
24+
return constraint ? $"{ConstraintPrefix}{baseName.TrimStart(EscapedPrefix)}#{arity}"
25+
: $"{baseName}#{arity}";
26+
}
27+
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
using System.Reflection;
2+
using RelogicLabs.JSchema.Exceptions;
3+
using RelogicLabs.JSchema.Tree;
4+
using RelogicLabs.JSchema.Utilities;
5+
using static RelogicLabs.JSchema.Message.ErrorCode;
6+
using static RelogicLabs.JSchema.Message.MessageFormatter;
7+
8+
namespace RelogicLabs.JSchema.Functions;
9+
10+
internal static class FunctionLoader
11+
{
12+
public static FunctionMap Load(Type providerImpl, Context? context = null)
13+
{
14+
var instance = CreateInstance(providerImpl, context);
15+
var providerBase = typeof(FunctionProvider);
16+
var functions = new FunctionMap();
17+
foreach(var m in providerImpl.GetMethods())
18+
{
19+
// Methods in ancestor class or in base class
20+
if(!providerBase.IsAssignableFrom(m.DeclaringType)
21+
|| providerBase == m.DeclaringType) continue;
22+
ParameterInfo[] parameters = m.GetParameters();
23+
if(!IsValidReturnType(m.ReturnType)) throw failOnReturnType(m, context);
24+
if(parameters.Length == 0 || parameters[0].IsParams())
25+
throw failOnTargetParameter(m, context);
26+
functions.Add(new NativeFunction(m, parameters, instance));
27+
}
28+
return functions;
29+
}
30+
31+
private static FunctionProvider CreateInstance(Type type, Context? context)
32+
{
33+
try
34+
{
35+
var instance = (FunctionProvider?) Activator.CreateInstance(type);
36+
if(instance != null) return instance;
37+
}
38+
catch(TargetInvocationException ex) { throw FailOnCreateInstance(INST01, ex, type, context); }
39+
catch(MissingMethodException ex) { throw FailOnCreateInstance(INST02, ex, type, context); }
40+
catch(MethodAccessException ex) { throw FailOnCreateInstance(INST03, ex, type, context); }
41+
catch(MemberAccessException ex) { throw FailOnCreateInstance(INST04, ex, type, context); }
42+
catch(TypeLoadException ex) { throw FailOnCreateInstance(INST05, ex, type, context); }
43+
catch(FileNotFoundException ex) { throw FailOnCreateInstance(INST06, ex, type, context); }
44+
catch(NotSupportedException ex) { throw FailOnCreateInstance(INST07, ex, type, context); }
45+
catch(BadImageFormatException ex) { throw FailOnCreateInstance(INST08, ex, type, context); }
46+
catch(FileLoadException ex) { throw FailOnCreateInstance(INST09, ex, type, context); }
47+
catch(Exception ex) { throw FailOnCreateInstance(INST10, ex, type, context); }
48+
throw FailOnCreateInstance(INST11, null, type, context);
49+
}
50+
51+
private static bool IsValidReturnType(Type type)
52+
{
53+
if(type == typeof(bool)) return true;
54+
if(type == typeof(FutureFunction)) return true;
55+
return false;
56+
}
57+
58+
private static ClassInstantiationException FailOnCreateInstance(string code, Exception? ex,
59+
Type type, Context? context)
60+
=> new(FormatForSchema(code, $"Fail to create instance of {type.FullName}", context), ex);
61+
62+
private static InvalidFunctionException failOnReturnType(MethodInfo method, Context? context)
63+
=> new(FormatForSchema(FUNC01, $"Function [{
64+
method.GetSignature()}] requires valid return type", context));
65+
66+
private static InvalidFunctionException failOnTargetParameter(MethodInfo method, Context? context)
67+
=> new(FormatForSchema(FUNC02, $"Function [{
68+
method.GetSignature()}] requires valid target parameter", context));
69+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
using RelogicLabs.JSchema.Tree;
2+
using RelogicLabs.JSchema.Utilities;
3+
4+
namespace RelogicLabs.JSchema.Functions;
5+
6+
internal sealed class FunctionMap
7+
{
8+
private readonly Dictionary<string, List<IEFunction>> _functions = new();
9+
10+
public void MergeWith(FunctionMap other)
11+
{
12+
foreach(var pair in other._functions)
13+
{
14+
_functions.TryGetValue(pair.Key, out var list);
15+
if(list == default) _functions.Add(pair.Key, pair.Value);
16+
else list.AddRange(pair.Value);
17+
}
18+
}
19+
20+
public void Add(IEFunction function)
21+
{
22+
var key = FunctionId.Generate(function);
23+
var list = _functions.TryGetValue(key) ?? new List<IEFunction>();
24+
list.Add(function);
25+
_functions[key] = list;
26+
}
27+
28+
public List<IEFunction>? TryGetValue(string key) => _functions.TryGetValue(key);
29+
}
Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
1-
using RelogicLabs.JSchema.Tree;
21
using RelogicLabs.JSchema.Nodes;
2+
using RelogicLabs.JSchema.Tree;
33

44
namespace RelogicLabs.JSchema.Functions;
55

66
public abstract class FunctionProvider
77
{
8-
public RuntimeContext Runtime { get; }
8+
public RuntimeContext Runtime { get; set; } = null!;
99
public JFunction Caller { get; set; } = null!;
1010

11-
protected FunctionProvider(RuntimeContext runtime) => Runtime = runtime;
12-
1311
protected bool Fail(Exception exception)
1412
=> Runtime.Exceptions.Fail(exception);
1513
}

JSchema/RelogicLabs/JSchema/Message/ActualDetail.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
using RelogicLabs.JSchema.Tree;
21
using RelogicLabs.JSchema.Nodes;
2+
using RelogicLabs.JSchema.Tree;
33

44
namespace RelogicLabs.JSchema.Message;
55

JSchema/RelogicLabs/JSchema/Message/ContextDetail.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
using RelogicLabs.JSchema.Tree;
21
using RelogicLabs.JSchema.Nodes;
2+
using RelogicLabs.JSchema.Tree;
33

44
namespace RelogicLabs.JSchema.Message;
55

0 commit comments

Comments
 (0)