Skip to content

Commit

Permalink
Fix null arguments preventing correct method overload finding
Browse files Browse the repository at this point in the history
- Fix issue where correct method overload would not be found when using a const `null` as input for a method.
  • Loading branch information
MerlinVR committed Nov 28, 2020
1 parent 2af31ff commit a0c13f3
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 13 deletions.
17 changes: 14 additions & 3 deletions Assets/UdonSharp/Editor/UdonSharpExpressionCapture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1460,19 +1460,30 @@ private SymbolDefinition HandleGenericUSharpGetComponent(MethodInfo targetMethod

private SymbolDefinition InvokeExtern(SymbolDefinition[] invokeParams)
{
// We use void as a placeholder for a null constant value getting passed in, if null is passed in and the target type is a reference type then we assume they are compatible
List<System.Type> typeList = invokeParams.Select(e =>
{
if (e.declarationType.HasFlag(SymbolDeclTypeFlags.Constant) &&
e.symbolCsType == typeof(object) &&
e.symbolDefaultValue == null)
return typeof(void);

return e.symbolCsType;
}).ToList();

// Find valid overrides
MethodBase targetMethod = visitorContext.resolverContext.FindBestOverloadFunction(captureMethods, invokeParams.Select(e => e.symbolCsType).ToList());
MethodBase targetMethod = visitorContext.resolverContext.FindBestOverloadFunction(captureMethods, typeList);

if (targetMethod == null)
{
targetMethod = visitorContext.resolverContext.FindBestOverloadFunction(captureMethods, invokeParams.Select(e => e.symbolCsType).ToList(), false);
targetMethod = visitorContext.resolverContext.FindBestOverloadFunction(captureMethods, typeList, false);

if (targetMethod != null &&
targetMethod.ReflectedType == typeof(VRC.Udon.UdonBehaviour) &&
targetMethod.Name.StartsWith("GetComponent") &&
((MethodInfo)targetMethod).ReturnType.IsGenericParameter)
{
// Uhh just skip the else stuff
// Uhh just skip the else stuff, this fixes GetComponent(s) on UdonBehaviour variables.
}
else
{
Expand Down
2 changes: 1 addition & 1 deletion Assets/UdonSharp/Editor/UdonSharpSymbolTable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public enum SymbolDeclTypeFlags
Private = 2, // Declared by the user as a private variable on a class
Local = 4, // Declared by the user as a variable local to a specific scope
Internal = 8, // Generated as an intermediate variable that stores intermediate calculations
Constant = 16, // Used to represent a constant value that does not change. This can either be statically defined constants
Constant = 16, // Used to represent a constant value set by the compiler that does not change after compile time. Variables with const/readonly use the Readonly flag.
Array = 32, // If this symbol is an array type
This = 64, // defines one of the 3 builtin `this` assignments for UdonBehaviour, GameObject, and Transform
Reflection = 128, // Metadata information for type checking and other editor time info
Expand Down
4 changes: 4 additions & 0 deletions Assets/UdonSharp/Editor/UdonSharpUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,10 @@ public static bool IsImplicitlyAssignableFrom(this System.Type targetType, Syste
if (IsNumericImplicitCastValid(targetType, assignee))
return true;

// We use void as a placeholder for a null constant value getting passed in, if null is passed in and the target type is a reference type then we assume they are compatible
if (assignee == typeof(void) && !targetType.IsValueType)
return true;

// Handle user-defined implicit conversion operators defined on both sides
// Roughly follows https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/conversions#processing-of-user-defined-implicit-conversions

Expand Down
16 changes: 7 additions & 9 deletions Assets/UdonSharp/Tests/TestScripts/Core/MethodCallsTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -91,16 +91,14 @@ public void ExecuteTests()
RigidbodyConstraints constraints = (RigidbodyConstraints)126;

tester.TestAssertion("Enum cast", constraints == RigidbodyConstraints.FreezeAll);
}

//public void test(int a, bool b, float c = 5f, params float[] d)
//{
// test(a, b);
//}
Transform currentParent = transform.parent;

transform.SetParent(null);

//public void test2(params object[] strings)
//{
// test2(new string[] { "aa", "bbb" });
//}
tester.TestAssertion("Transform detach parent (null parameter method finding)", transform.parent == null);

transform.SetParent(currentParent);
}
}
}

0 comments on commit a0c13f3

Please sign in to comment.