예제 #1
0
        public bool MethodNeedsExport(MethodSymbol methodSymbol)
        {
            if (methodSymbol.IsStatic)
            {
                return(false);
            }

            if (GetMostDerivedMethod(methodSymbol) != methodSymbol)
            {
                return(false);
            }

            return(methodSymbol.RoslynSymbol.DeclaredAccessibility == Accessibility.Public ||
                   CompilerUdonInterface.IsUdonEvent(methodSymbol.Name) ||
                   (methodSymbol is UdonSharpBehaviourMethodSymbol udonSharpBehaviourMethodSymbol && udonSharpBehaviourMethodSymbol.NeedsExportFromReference));
        }
예제 #2
0
        private MethodExportLayout BuildMethodLayout(MethodSymbol methodSymbol, Dictionary <string, int> idLookup)
        {
            string methodName = methodSymbol.Name;

            string[] paramNames = new string[methodSymbol.Parameters.Length];
            string   returnName = null;

            if (CompilerUdonInterface.IsUdonEvent(methodName))
            {
                var paramArgs = CompilerUdonInterface.GetUdonEventArgs(methodName);
                methodName = CompilerUdonInterface.GetUdonEventName(methodName);

                for (int i = 0; i < paramNames.Length; ++i)
                {
                    paramNames[i] = paramArgs[i].Item1;
                }
            }
            else
            {
                if (methodSymbol.Parameters.Length > 0) // Do not mangle 0 parameter methods as they may be called externally
                {
                    methodName = GetUniqueID(idLookup, methodName);
                }

                for (int i = 0; i < paramNames.Length; ++i)
                {
                    paramNames[i] = GetUniqueID(idLookup, methodSymbol.Parameters[i].Name + "__param");
                }
            }

            if (methodSymbol.ReturnType != null)
            {
                returnName = GetUniqueID(idLookup, methodName + "__ret");
            }

            MethodExportLayout exportLayout = new MethodExportLayout(methodSymbol, methodName, returnName, paramNames);

            _layouts.Add(methodSymbol, exportLayout);

            return(exportLayout);
        }
 public UdonSharpBehaviourMethodSymbol(IMethodSymbol sourceSymbol, AbstractPhaseContext context)
     : base(sourceSymbol, context)
 {
     IsUdonEvent           = CompilerUdonInterface.IsUdonEvent(sourceSymbol.Name);
     ExportedMethodAddress = new ExportAddress(ExportAddress.AddressKind.String, this);
 }
        public static BoundInvocationExpression CreateBoundInvocation(AbstractPhaseContext context, SyntaxNode node,
                                                                      MethodSymbol symbol, BoundExpression instanceExpression, BoundExpression[] parameterExpressions)
        {
            if (TryCreateShimInvocation(context, node, symbol, instanceExpression, parameterExpressions, out var boundShimInvocation))
            {
                return(boundShimInvocation);
            }

            if (symbol.IsExtern)
            {
                if (CompilerUdonInterface.IsUdonEvent(symbol.Name) &&
                    symbol.ContainingType == context.GetTypeSymbol(typeof(UdonSharpBehaviour))) // Pass through for making base calls on the U# behaviour type return noop
                {
                    return(new BoundUdonSharpBehaviourInvocationExpression(node, symbol, instanceExpression, parameterExpressions));
                }

                if (symbol.IsOperator)
                {
                    // Enum equality/inequality
                    if (symbol.ContainingType?.IsEnum ?? false)
                    {
                        MethodSymbol objectEqualsMethod = context.GetTypeSymbol(SpecialType.System_Object)
                                                          .GetMember <MethodSymbol>("Equals", context);

                        var boundEqualsInvocation = CreateBoundInvocation(context, node, objectEqualsMethod, parameterExpressions[0],
                                                                          new[] { parameterExpressions[1] });
                        if (symbol.Name == "op_Equality")
                        {
                            return(boundEqualsInvocation);
                        }

                        MethodSymbol boolNotOperator = new ExternSynthesizedOperatorSymbol(
                            BuiltinOperatorType.UnaryNegation, context.GetTypeSymbol(SpecialType.System_Boolean),
                            context);

                        return(new BoundExternInvocation(node, context, boolNotOperator, null, new BoundExpression[] { boundEqualsInvocation }));
                    }

                    if (node is AssignmentExpressionSyntax)
                    {
                        return(new BoundCompoundAssignmentExpression(context, node, (BoundAccessExpression)parameterExpressions[0], symbol, parameterExpressions[1]));
                    }

                    if (symbol is ExternBuiltinOperatorSymbol externBuiltinOperatorSymbol &&
                        externBuiltinOperatorSymbol.OperatorType == BuiltinOperatorType.BitwiseNot)
                    {
                        return(new BoundBitwiseNotExpression(node, parameterExpressions[0]));
                    }

                    if (parameterExpressions.Length == 2 || symbol.Name == "op_UnaryNegation" || symbol.Name == "op_LogicalNot")
                    {
                        return(new BoundBuiltinOperatorInvocationExpression(node, context, symbol, parameterExpressions));
                    }

                    throw new NotSupportedException("Operator expressions must have either 1 or 2 parameters", node.GetLocation());
                }

                return(new BoundExternInvocation(node, context, symbol, instanceExpression, parameterExpressions));
            }

            if (symbol.IsStatic)
            {
                return(new BoundStaticUserMethodInvocation(node, symbol, parameterExpressions));
            }

            if (symbol is UdonSharpBehaviourMethodSymbol udonSharpBehaviourMethodSymbol)
            {
                if (instanceExpression != null && !instanceExpression.IsThis)
                {
                    udonSharpBehaviourMethodSymbol.MarkNeedsReferenceExport();
                }

                return(new BoundUdonSharpBehaviourInvocationExpression(node, symbol, instanceExpression,
                                                                       parameterExpressions));
            }

            throw new System.NotImplementedException();
        }