Skip to content

Commit

Permalink
Fix null checks on UnityEngine.Object types
Browse files Browse the repository at this point in the history
- Unity has special handling for checking if a UnityEngine.Object is null or not that has unexpected different behavior from how System.Object compares things. This was causing issues to always use System.Object equality on all null checks since some Unity functions return a non-null object that is still considered "null" by unity.
  • Loading branch information
MerlinVR committed Mar 6, 2020
1 parent 2c20e9f commit 95aaa8e
Showing 1 changed file with 26 additions and 1 deletion.
27 changes: 26 additions & 1 deletion Assets/UdonSharp/Editor/UdonSharpASTVisitor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1114,7 +1114,13 @@ private MethodInfo[] GetOperators(System.Type type, BuiltinOperatorType builtinO

operatorName = $"op_{operatorName}";

foundOperators.AddRange(type.GetMethods(BindingFlags.Public | BindingFlags.Static).Where(e => e.Name == operatorName));
System.Type currentType = type;

while (currentType != null)
{
foundOperators.AddRange(currentType.GetMethods(BindingFlags.Public | BindingFlags.Static).Where(e => e.Name == operatorName));
currentType = currentType.BaseType;
}

// Add the object equality and inequality operators if we haven't already found better matches
if (foundOperators.Count == 0 && type != typeof(object) && !type.IsValueType &&
Expand Down Expand Up @@ -1446,6 +1452,25 @@ public override void VisitBinaryExpression(BinaryExpressionSyntax node)

SymbolDefinition resultSymbol = null;

BuiltinOperatorType operatorType = SyntaxKindToBuiltinOperator(node.Kind());

// Basic handling for handling null equality/inequality on derived types since Unity has special behavior for comparing UnityEngine.Object types to null
if (operatorType == BuiltinOperatorType.Equality ||
operatorType == BuiltinOperatorType.Inequality)
{
bool lhsNull = lhsValue.declarationType.HasFlag(SymbolDeclTypeFlags.Constant) && lhsValue.symbolDefaultValue == null;
bool rhsNull = rhsValue.declarationType.HasFlag(SymbolDeclTypeFlags.Constant) && rhsValue.symbolDefaultValue == null;

if (lhsNull && !rhsNull)
{
lhsValue = visitorContext.topTable.CreateConstSymbol(rhsType, null);
}
else if (rhsNull && !lhsNull)
{
rhsValue = visitorContext.topTable.CreateConstSymbol(lhsType, null);
}
}

try
{
resultSymbol = operatorMethodCapture.Invoke(new SymbolDefinition[] { lhsValue, rhsValue });
Expand Down

0 comments on commit 95aaa8e

Please sign in to comment.