private static bool TryCreateGetComponentInvocation(AbstractPhaseContext context, SyntaxNode node, MethodSymbol symbol, BoundExpression instanceExpression, BoundExpression[] parameterExpressions, out BoundInvocationExpression createdInvocation) { if (symbol.RoslynSymbol != null && symbol.RoslynSymbol.IsGenericMethod && symbol.TypeArguments.Length == 1 && _getComponentNames.Contains(symbol.Name) && (symbol.ContainingType.UdonType.SystemType == typeof(Component) || symbol.ContainingType.UdonType.SystemType == typeof(GameObject))) { TypeSymbol gameObjectType = context.GetTypeSymbol(typeof(GameObject)); TypeSymbol typeArgument = symbol.TypeArguments[0]; // udon-workaround: Work around the udon bug where it checks the strongbox type instead of variable type and blows up when the strong box is `object` if (instanceExpression.ValueType == gameObjectType) { PropertySymbol accessProperty = gameObjectType.GetMember <PropertySymbol>("transform", context); instanceExpression = BoundAccessExpression.BindAccess(context, node, accessProperty, instanceExpression); } else { PropertySymbol accessProperty = context.GetTypeSymbol(typeof(Component)).GetMember <PropertySymbol>("transform", context); instanceExpression = BoundAccessExpression.BindAccess(context, node, accessProperty, instanceExpression); } TypeSymbol udonSharpBehaviourType = context.GetTypeSymbol(typeof(UdonSharpBehaviour)); // Exact UdonSharpBehaviour type match if (typeArgument == udonSharpBehaviourType) { MethodSymbol getComponentMethodShim = context.GetTypeSymbol(typeof(GetComponentShim)) .GetMembers <MethodSymbol>(symbol.Name + "USB", context) .First(e => e.Parameters.Length == parameterExpressions.Length + 1); createdInvocation = new BoundStaticUserMethodInvocation(node, getComponentMethodShim, new [] { instanceExpression }.Concat(parameterExpressions).ToArray()); context.MarkSymbolReferenced(getComponentMethodShim); return(true); } // Subclass of UdonSharpBehaviour if (typeArgument.IsUdonSharpBehaviour) { // Handle inherited types if (context.CompileContext.HasInheritedUdonSharpBehaviours(typeArgument)) { MethodSymbol getComponentInheritedMethodShim = context.GetTypeSymbol(typeof(GetComponentShim)) .GetMembers <MethodSymbol>(symbol.Name + "I", context) .First(e => e.Parameters.Length == parameterExpressions.Length + 1); getComponentInheritedMethodShim = getComponentInheritedMethodShim.ConstructGenericMethod(context, new [] { typeArgument }); createdInvocation = new BoundStaticUserMethodInvocation(node, getComponentInheritedMethodShim, new [] { instanceExpression }.Concat(parameterExpressions).ToArray()); context.MarkSymbolReferenced(getComponentInheritedMethodShim); return(true); } MethodSymbol getComponentMethodShim = context.GetTypeSymbol(typeof(GetComponentShim)) .GetMembers <MethodSymbol>(symbol.Name, context) .First(e => e.Parameters.Length == parameterExpressions.Length + 1); getComponentMethodShim = getComponentMethodShim.ConstructGenericMethod(context, new [] { typeArgument }); createdInvocation = new BoundStaticUserMethodInvocation(node, getComponentMethodShim, new [] { instanceExpression }.Concat(parameterExpressions).ToArray()); context.MarkSymbolReferenced(getComponentMethodShim); return(true); } if (_brokenGetComponentTypes.Contains(typeArgument.UdonType.SystemType)) { MethodSymbol getComponentInheritedMethodShim = context.GetTypeSymbol(typeof(GetComponentShim)) .GetMembers <MethodSymbol>(symbol.Name + "VRC", context) .First(e => e.Parameters.Length == parameterExpressions.Length + 1); getComponentInheritedMethodShim = getComponentInheritedMethodShim.ConstructGenericMethod(context, new [] { typeArgument }); createdInvocation = new BoundStaticUserMethodInvocation(node, getComponentInheritedMethodShim, new [] { instanceExpression }.Concat(parameterExpressions).ToArray()); context.MarkSymbolReferenced(getComponentInheritedMethodShim); return(true); } createdInvocation = new BoundGetUnityEngineComponentInvocation(context, node, symbol, instanceExpression, parameterExpressions); return(true); } createdInvocation = null; return(false); }