Skip to content

Commit 4e748a7

Browse files
authored
Merge pull request #267 from wledfor2/caseoptions
Added Options to control "fuzzy" matching of userdata methods, etc
2 parents af8b2a7 + c2ed234 commit 4e748a7

11 files changed

Lines changed: 109 additions & 32 deletions

File tree

src/MoonSharp.Interpreter/Interop/BasicDescriptors/DispatchingUserDataDescriptor.cs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -233,18 +233,18 @@ public virtual DynValue Index(Script script, object obj, DynValue index, bool is
233233
return null;
234234

235235
DynValue v = TryIndex(script, obj, index.String);
236-
if (v == null) v = TryIndex(script, obj, UpperFirstLetter(index.String));
237-
if (v == null) v = TryIndex(script, obj, Camelify(index.String));
238-
if (v == null) v = TryIndex(script, obj, UpperFirstLetter(Camelify(index.String)));
236+
if (v == null && (Script.GlobalOptions.FuzzySymbolMatching & FuzzySymbolMatchingBehavior.UpperFirstLetter) == FuzzySymbolMatchingBehavior.UpperFirstLetter) v = TryIndex(script, obj, UpperFirstLetter(index.String));
237+
if (v == null && (Script.GlobalOptions.FuzzySymbolMatching & FuzzySymbolMatchingBehavior.Camelify) == FuzzySymbolMatchingBehavior.Camelify) v = TryIndex(script, obj, Camelify(index.String));
238+
if (v == null && (Script.GlobalOptions.FuzzySymbolMatching & FuzzySymbolMatchingBehavior.PascalCase) == FuzzySymbolMatchingBehavior.PascalCase) v = TryIndex(script, obj, UpperFirstLetter(Camelify(index.String)));
239239

240240
if (v == null && m_ExtMethodsVersion < UserData.GetExtensionMethodsChangeVersion())
241241
{
242242
m_ExtMethodsVersion = UserData.GetExtensionMethodsChangeVersion();
243243

244244
v = TryIndexOnExtMethod(script, obj, index.String);
245-
if (v == null) v = TryIndexOnExtMethod(script, obj, UpperFirstLetter(index.String));
246-
if (v == null) v = TryIndexOnExtMethod(script, obj, Camelify(index.String));
247-
if (v == null) v = TryIndexOnExtMethod(script, obj, UpperFirstLetter(Camelify(index.String)));
245+
if (v == null && (Script.GlobalOptions.FuzzySymbolMatching & FuzzySymbolMatchingBehavior.UpperFirstLetter) == FuzzySymbolMatchingBehavior.UpperFirstLetter) v = TryIndexOnExtMethod(script, obj, UpperFirstLetter(index.String));
246+
if (v == null && (Script.GlobalOptions.FuzzySymbolMatching & FuzzySymbolMatchingBehavior.Camelify) == FuzzySymbolMatchingBehavior.Camelify) v = TryIndexOnExtMethod(script, obj, Camelify(index.String));
247+
if (v == null && (Script.GlobalOptions.FuzzySymbolMatching & FuzzySymbolMatchingBehavior.PascalCase) == FuzzySymbolMatchingBehavior.PascalCase) v = TryIndexOnExtMethod(script, obj, UpperFirstLetter(Camelify(index.String)));
248248
}
249249

250250
return v;
@@ -344,9 +344,9 @@ public virtual bool SetIndex(Script script, object obj, DynValue index, DynValue
344344
return false;
345345

346346
bool v = TrySetIndex(script, obj, index.String, value);
347-
if (!v) v = TrySetIndex(script, obj, UpperFirstLetter(index.String), value);
348-
if (!v) v = TrySetIndex(script, obj, Camelify(index.String), value);
349-
if (!v) v = TrySetIndex(script, obj, UpperFirstLetter(Camelify(index.String)), value);
347+
if (!v && (Script.GlobalOptions.FuzzySymbolMatching & FuzzySymbolMatchingBehavior.UpperFirstLetter) == FuzzySymbolMatchingBehavior.UpperFirstLetter) v = TrySetIndex(script, obj, UpperFirstLetter(index.String), value);
348+
if (!v && (Script.GlobalOptions.FuzzySymbolMatching & FuzzySymbolMatchingBehavior.Camelify) == FuzzySymbolMatchingBehavior.Camelify) v = TrySetIndex(script, obj, Camelify(index.String), value);
349+
if (!v && (Script.GlobalOptions.FuzzySymbolMatching & FuzzySymbolMatchingBehavior.PascalCase) == FuzzySymbolMatchingBehavior.PascalCase) v = TrySetIndex(script, obj, UpperFirstLetter(Camelify(index.String)), value);
350350

351351
return v;
352352
}

src/MoonSharp.Interpreter/Interop/PropertyTableAssigner.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -182,9 +182,9 @@ private bool TryAssignProperty(object obj, string name, DynValue value)
182182
private void AssignProperty(object obj, string name, DynValue value)
183183
{
184184
if (TryAssignProperty(obj, name, value)) return;
185-
if (TryAssignProperty(obj, DescriptorHelpers.UpperFirstLetter(name), value)) return;
186-
if (TryAssignProperty(obj, DescriptorHelpers.Camelify(name), value)) return;
187-
if (TryAssignProperty(obj, DescriptorHelpers.UpperFirstLetter(DescriptorHelpers.Camelify(name)), value)) return;
185+
if ((Script.GlobalOptions.FuzzySymbolMatching & FuzzySymbolMatchingBehavior.UpperFirstLetter) == FuzzySymbolMatchingBehavior.UpperFirstLetter && TryAssignProperty(obj, DescriptorHelpers.UpperFirstLetter(name), value)) return;
186+
if ((Script.GlobalOptions.FuzzySymbolMatching & FuzzySymbolMatchingBehavior.Camelify) == FuzzySymbolMatchingBehavior.Camelify && TryAssignProperty(obj, DescriptorHelpers.Camelify(name), value)) return;
187+
if ((Script.GlobalOptions.FuzzySymbolMatching & FuzzySymbolMatchingBehavior.PascalCase) == FuzzySymbolMatchingBehavior.PascalCase && TryAssignProperty(obj, DescriptorHelpers.UpperFirstLetter(DescriptorHelpers.Camelify(name)), value)) return;
188188

189189
throw new ScriptRuntimeException("Invalid property {0}", name);
190190
}

src/MoonSharp.Interpreter/MoonSharp.Interpreter.net35-client.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,7 @@
302302
<Compile Include="Loaders\FileSystemScriptLoader.cs" />
303303
<Compile Include="Loaders\InvalidScriptLoader.cs" />
304304
<Compile Include="Options\ColonOperatorBehaviour.cs" />
305+
<Compile Include="Options\FuzzySymbolMatchingBehavior.cs" />
305306
<Compile Include="Platforms\DotNetCorePlatformAccessor.cs" />
306307
<Compile Include="REPL\ReplHistoryNavigator.cs" />
307308
<Compile Include="REPL\ReplInterpreterScriptLoader.cs" />
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
using System;
2+
3+
namespace MoonSharp.Interpreter {
4+
5+
/// <summary>
6+
/// A flag that controls if/how symbols (method, property, userdata) are fuzzily matched when they do not exist. Flags can be combined for multiple checks.
7+
/// </summary>
8+
[Flags]
9+
public enum FuzzySymbolMatchingBehavior {
10+
11+
/// <summary>No fuzzy matching is performed.</summary>
12+
None = 0,
13+
14+
/// <summary>The first letter of a symbol will be uppercased (to check for common C# naming conventions). For example, testMethod() becomes TestMethod()</summary>
15+
UpperFirstLetter = 1,
16+
17+
/// <summary>Underscores in symbols are converted to camelcase. For example, test_method() becomes testMethod()</summary>
18+
Camelify = 2,
19+
20+
/// <summary>
21+
/// Converts a symbol to pascal case. For example, test_Method_two() becomes TestMethodTwo()
22+
/// </summary>
23+
PascalCase = 4
24+
25+
}
26+
27+
}

src/MoonSharp.Interpreter/ScriptGlobalOptions.cs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
using MoonSharp.Interpreter.Interop;
22
using MoonSharp.Interpreter.Platforms;
3+
using MoonSharp.Interpreter;
34

45
namespace MoonSharp.Interpreter
56
{
67
/// <summary>
78
/// Class containing script global options, that is options which cannot be customized per-script.
89
/// <see cref="Script.GlobalOptions"/>
910
/// </summary>
10-
public class ScriptGlobalOptions
11-
{
12-
internal ScriptGlobalOptions()
13-
{
11+
public class ScriptGlobalOptions {
12+
internal ScriptGlobalOptions() {
1413
Platform = PlatformAutoDetector.GetDefaultPlatform();
1514
CustomConverters = new CustomConvertersCollection();
15+
FuzzySymbolMatching = FuzzySymbolMatchingBehavior.Camelify | FuzzySymbolMatchingBehavior.UpperFirstLetter | FuzzySymbolMatchingBehavior.PascalCase;
1616
}
1717

1818
/// <summary>
@@ -33,5 +33,13 @@ internal ScriptGlobalOptions()
3333
/// re-thrown as nested exceptions.
3434
/// </summary>
3535
public bool RethrowExceptionNested { get; set; }
36+
37+
/// <summary>
38+
/// Gets or sets an enum that controls behaviour when a symbol (method, property, userdata) is not found in a userdata's descriptor. For instance,
39+
/// when this value is <see cref="FuzzySymbolMatchingBehavior.UpperFirstLetter"/> and Lua code calls the non-existent method <c>someuserdata.someMethod()</c>,
40+
/// <c>someuserdata.SomeMethod()</c> will also be tried.
41+
/// </summary>
42+
public FuzzySymbolMatchingBehavior FuzzySymbolMatching { get; set; }
43+
3644
}
3745
}

src/MoonSharp.Interpreter/_Projects/MoonSharp.Interpreter.net40-client/MoonSharp.Interpreter.net40-client.csproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -576,6 +576,9 @@
576576
<Compile Include="..\..\Options\ColonOperatorBehaviour.cs">
577577
<Link>ColonOperatorBehaviour.cs</Link>
578578
</Compile>
579+
<Compile Include="..\..\Options\FuzzySymbolMatchingBehavior.cs">
580+
<Link>FuzzySymbolMatchingBehaviour.cs</Link>
581+
</Compile>
579582
<Compile Include="..\..\Platforms\DotNetCorePlatformAccessor.cs">
580583
<Link>DotNetCorePlatformAccessor.cs</Link>
581584
</Compile>

src/MoonSharp.Interpreter/_Projects/MoonSharp.Interpreter.netcore/src/Interop/BasicDescriptors/DispatchingUserDataDescriptor.cs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -233,18 +233,18 @@ public virtual DynValue Index(Script script, object obj, DynValue index, bool is
233233
return null;
234234

235235
DynValue v = TryIndex(script, obj, index.String);
236-
if (v == null) v = TryIndex(script, obj, UpperFirstLetter(index.String));
237-
if (v == null) v = TryIndex(script, obj, Camelify(index.String));
238-
if (v == null) v = TryIndex(script, obj, UpperFirstLetter(Camelify(index.String)));
236+
if (v == null && (Script.GlobalOptions.FuzzySymbolMatching & FuzzySymbolMatchingBehavior.UpperFirstLetter) == FuzzySymbolMatchingBehavior.UpperFirstLetter) v = TryIndex(script, obj, UpperFirstLetter(index.String));
237+
if (v == null && (Script.GlobalOptions.FuzzySymbolMatching & FuzzySymbolMatchingBehavior.Camelify) == FuzzySymbolMatchingBehavior.Camelify) v = TryIndex(script, obj, Camelify(index.String));
238+
if (v == null && (Script.GlobalOptions.FuzzySymbolMatching & FuzzySymbolMatchingBehavior.PascalCase) == FuzzySymbolMatchingBehavior.PascalCase) v = TryIndex(script, obj, UpperFirstLetter(Camelify(index.String)));
239239

240240
if (v == null && m_ExtMethodsVersion < UserData.GetExtensionMethodsChangeVersion())
241241
{
242242
m_ExtMethodsVersion = UserData.GetExtensionMethodsChangeVersion();
243243

244244
v = TryIndexOnExtMethod(script, obj, index.String);
245-
if (v == null) v = TryIndexOnExtMethod(script, obj, UpperFirstLetter(index.String));
246-
if (v == null) v = TryIndexOnExtMethod(script, obj, Camelify(index.String));
247-
if (v == null) v = TryIndexOnExtMethod(script, obj, UpperFirstLetter(Camelify(index.String)));
245+
if (v == null && (Script.GlobalOptions.FuzzySymbolMatching & FuzzySymbolMatchingBehavior.UpperFirstLetter) == FuzzySymbolMatchingBehavior.UpperFirstLetter) v = TryIndexOnExtMethod(script, obj, UpperFirstLetter(index.String));
246+
if (v == null && (Script.GlobalOptions.FuzzySymbolMatching & FuzzySymbolMatchingBehavior.Camelify) == FuzzySymbolMatchingBehavior.Camelify) v = TryIndexOnExtMethod(script, obj, Camelify(index.String));
247+
if (v == null && (Script.GlobalOptions.FuzzySymbolMatching & FuzzySymbolMatchingBehavior.PascalCase) == FuzzySymbolMatchingBehavior.PascalCase) v = TryIndexOnExtMethod(script, obj, UpperFirstLetter(Camelify(index.String)));
248248
}
249249

250250
return v;
@@ -344,9 +344,9 @@ public virtual bool SetIndex(Script script, object obj, DynValue index, DynValue
344344
return false;
345345

346346
bool v = TrySetIndex(script, obj, index.String, value);
347-
if (!v) v = TrySetIndex(script, obj, UpperFirstLetter(index.String), value);
348-
if (!v) v = TrySetIndex(script, obj, Camelify(index.String), value);
349-
if (!v) v = TrySetIndex(script, obj, UpperFirstLetter(Camelify(index.String)), value);
347+
if (!v && (Script.GlobalOptions.FuzzySymbolMatching & FuzzySymbolMatchingBehavior.UpperFirstLetter) == FuzzySymbolMatchingBehavior.UpperFirstLetter) v = TrySetIndex(script, obj, UpperFirstLetter(index.String), value);
348+
if (!v && (Script.GlobalOptions.FuzzySymbolMatching & FuzzySymbolMatchingBehavior.Camelify) == FuzzySymbolMatchingBehavior.Camelify) v = TrySetIndex(script, obj, Camelify(index.String), value);
349+
if (!v && (Script.GlobalOptions.FuzzySymbolMatching & FuzzySymbolMatchingBehavior.PascalCase) == FuzzySymbolMatchingBehavior.PascalCase) v = TrySetIndex(script, obj, UpperFirstLetter(Camelify(index.String)), value);
350350

351351
return v;
352352
}

src/MoonSharp.Interpreter/_Projects/MoonSharp.Interpreter.netcore/src/Interop/PropertyTableAssigner.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -182,9 +182,9 @@ private bool TryAssignProperty(object obj, string name, DynValue value)
182182
private void AssignProperty(object obj, string name, DynValue value)
183183
{
184184
if (TryAssignProperty(obj, name, value)) return;
185-
if (TryAssignProperty(obj, DescriptorHelpers.UpperFirstLetter(name), value)) return;
186-
if (TryAssignProperty(obj, DescriptorHelpers.Camelify(name), value)) return;
187-
if (TryAssignProperty(obj, DescriptorHelpers.UpperFirstLetter(DescriptorHelpers.Camelify(name)), value)) return;
185+
if ((Script.GlobalOptions.FuzzySymbolMatching & FuzzySymbolMatchingBehavior.UpperFirstLetter) == FuzzySymbolMatchingBehavior.UpperFirstLetter && TryAssignProperty(obj, DescriptorHelpers.UpperFirstLetter(name), value)) return;
186+
if ((Script.GlobalOptions.FuzzySymbolMatching & FuzzySymbolMatchingBehavior.Camelify) == FuzzySymbolMatchingBehavior.Camelify && TryAssignProperty(obj, DescriptorHelpers.Camelify(name), value)) return;
187+
if ((Script.GlobalOptions.FuzzySymbolMatching & FuzzySymbolMatchingBehavior.PascalCase) == FuzzySymbolMatchingBehavior.PascalCase && TryAssignProperty(obj, DescriptorHelpers.UpperFirstLetter(DescriptorHelpers.Camelify(name)), value)) return;
188188

189189
throw new ScriptRuntimeException("Invalid property {0}", name);
190190
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
using System;
2+
3+
namespace MoonSharp.Interpreter {
4+
5+
/// <summary>
6+
/// A flag that controls if/how symbols (method, property, userdata) are fuzzily matched when they do not exist. Flags can be combined for multiple checks.
7+
/// </summary>
8+
[Flags]
9+
public enum FuzzySymbolMatchingBehavior {
10+
11+
/// <summary>No fuzzy matching is performed.</summary>
12+
None = 0,
13+
14+
/// <summary>The first letter of a symbol will be uppercased (to check for common C# naming conventions). For example, testMethod() becomes TestMethod()</summary>
15+
UpperFirstLetter = 1,
16+
17+
/// <summary>Underscores in symbols are converted to camelcase. For example, test_method() becomes testMethod()</summary>
18+
Camelify = 2,
19+
20+
/// <summary>
21+
/// Converts a symbol to pascal case. For example, test_Method_two() becomes TestMethodTwo()
22+
/// </summary>
23+
PascalCase = 4
24+
25+
}
26+
27+
}

src/MoonSharp.Interpreter/_Projects/MoonSharp.Interpreter.netcore/src/ScriptGlobalOptions.cs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
using MoonSharp.Interpreter.Interop;
22
using MoonSharp.Interpreter.Platforms;
3+
using MoonSharp.Interpreter;
34

45
namespace MoonSharp.Interpreter
56
{
67
/// <summary>
78
/// Class containing script global options, that is options which cannot be customized per-script.
89
/// <see cref="Script.GlobalOptions"/>
910
/// </summary>
10-
public class ScriptGlobalOptions
11-
{
12-
internal ScriptGlobalOptions()
13-
{
11+
public class ScriptGlobalOptions {
12+
internal ScriptGlobalOptions() {
1413
Platform = PlatformAutoDetector.GetDefaultPlatform();
1514
CustomConverters = new CustomConvertersCollection();
15+
FuzzySymbolMatching = FuzzySymbolMatchingBehavior.Camelify | FuzzySymbolMatchingBehavior.UpperFirstLetter | FuzzySymbolMatchingBehavior.PascalCase;
1616
}
1717

1818
/// <summary>
@@ -33,5 +33,13 @@ internal ScriptGlobalOptions()
3333
/// re-thrown as nested exceptions.
3434
/// </summary>
3535
public bool RethrowExceptionNested { get; set; }
36+
37+
/// <summary>
38+
/// Gets or sets an enum that controls behaviour when a symbol (method, property, userdata) is not found in a userdata's descriptor. For instance,
39+
/// when this value is <see cref="FuzzySymbolMatchingBehavior.UpperFirstLetter"/> and Lua code calls the non-existent method <c>someuserdata.someMethod()</c>,
40+
/// <c>someuserdata.SomeMethod()</c> will also be tried.
41+
/// </summary>
42+
public FuzzySymbolMatchingBehavior FuzzySymbolMatching { get; set; }
43+
3644
}
3745
}

0 commit comments

Comments
 (0)