public ExternSynthesizedOperatorSymbol(BuiltinOperatorType operatorType, TypeSymbol type, AbstractPhaseContext context)
            : base(null, context)
        {
            TypeSymbol boolType = context.GetTypeSymbol(SpecialType.System_Boolean);

            if (type == boolType && operatorType == BuiltinOperatorType.UnaryNegation)
            {
                Parameters = new[] { new ParameterSymbol(type, context) }.ToImmutableArray();
            }
            else
            {
                if ((operatorType == BuiltinOperatorType.LeftShift || operatorType == BuiltinOperatorType.RightShift) &&
                    (type == context.GetTypeSymbol(SpecialType.System_UInt32) ||
                     type == context.GetTypeSymbol(SpecialType.System_UInt64) ||
                     type == context.GetTypeSymbol(SpecialType.System_Int64)))
                {
                    Parameters = new[]
                    {
                        new ParameterSymbol(type, context),
                        new ParameterSymbol(context.GetTypeSymbol(SpecialType.System_Int32), context)
                    }.ToImmutableArray();
                }
                else
                {
                    Parameters = new[] { new ParameterSymbol(type, context), new ParameterSymbol(type, context) }
                }
Пример #2
0
        protected MethodSymbol(IMethodSymbol sourceSymbol, AbstractPhaseContext context)
            : base(sourceSymbol, context)
        {
            if (sourceSymbol != null)
            {
                ContainingType = context.GetTypeSymbol(sourceSymbol.ContainingType);
                IsConstructor  = sourceSymbol.MethodKind == MethodKind.Constructor;

                ITypeSymbol returnType = sourceSymbol.ReturnType;

                if (returnType != context.GetTypeSymbol(SpecialType.System_Void).RoslynSymbol)
                {
                    ReturnType = context.GetTypeSymbol(returnType);
                }
                else if (IsConstructor)
                {
                    ReturnType = context.GetTypeSymbol(sourceSymbol.ContainingType);
                }

                if (sourceSymbol.Parameters != null)
                {
                    List <ParameterSymbol> parameterSymbols = new List <ParameterSymbol>();

                    foreach (IParameterSymbol parameterSymbol in sourceSymbol.Parameters)
                    {
                        ParameterSymbol newSymbol = (ParameterSymbol)context.GetSymbol(parameterSymbol);

                        parameterSymbols.Add(newSymbol);
                    }

                    Parameters = ImmutableArray.CreateRange <ParameterSymbol>(parameterSymbols);
                }
                else
                {
                    Parameters = ImmutableArray <ParameterSymbol> .Empty;
                }

                if (!IsGenericMethod && RoslynSymbol != RoslynSymbol.OriginalDefinition)
                {
                    TypeArguments = sourceSymbol.TypeArguments.Length > 0 ? sourceSymbol.TypeArguments.Select(context.GetTypeSymbol).ToImmutableArray() : ImmutableArray <TypeSymbol> .Empty;
                }
                else
                {
                    TypeArguments = sourceSymbol.TypeArguments.Length > 0 ? sourceSymbol.TypeArguments.Select(context.GetTypeSymbolWithoutRedirect).ToImmutableArray() : ImmutableArray <TypeSymbol> .Empty;
                }

                if (RoslynSymbol.IsOverride && RoslynSymbol.OverriddenMethod != null) // abstract methods can be overrides, but not have overriden methods
                {
                    OverridenMethod = (MethodSymbol)context.GetSymbol(RoslynSymbol.OverriddenMethod);
                }

                IsOperator = RoslynSymbol.MethodKind == MethodKind.BuiltinOperator ||
                             RoslynSymbol.MethodKind == MethodKind.UserDefinedOperator;

                if (RoslynSymbol.OriginalDefinition != RoslynSymbol)
                {
                    OriginalSymbol = context.GetSymbolNoRedirect(RoslynSymbol.OriginalDefinition);
                }
            }
        }
        public BoundStringAccessExpression(AbstractPhaseContext context, SyntaxNode node, BoundExpression sourceExpression, BoundExpression indexerExpression)
            : base(node, sourceExpression)
        {
            IndexerExpression = indexerExpression;
            ValueType         = context.GetTypeSymbol(SpecialType.System_Char);

            _toCharArraySymbol = context.GetTypeSymbol(SpecialType.System_String).GetMembers <MethodSymbol>(nameof(string.ToCharArray), context).First(e => e.Parameters.Length == 2);
        }
Пример #4
0
        public LocalSymbol(ILocalSymbol sourceSymbol, AbstractPhaseContext bindContext)
            : base(sourceSymbol, bindContext)
        {
            if (!(bindContext is BindContext))
            {
                throw new InvalidOperationException("Local Symbols can only be created during the bind phase");
            }

            ContainingType = bindContext.GetTypeSymbol(sourceSymbol.ContainingType);
            Type           = bindContext.GetTypeSymbol(sourceSymbol.Type);
        }
 public ImportedUdonSharpTypeSymbol(IArrayTypeSymbol sourceSymbol, AbstractPhaseContext context)
     : base(sourceSymbol, context)
 {
     if (sourceSymbol.ElementType.TypeKind == TypeKind.Enum)
     {
         UdonType = (ExternTypeSymbol)context.GetTypeSymbol(((INamedTypeSymbol)sourceSymbol.ElementType).EnumUnderlyingType).UdonType.MakeArrayType(context);
     }
     else
     {
         UdonType = context.GetTypeSymbol(typeof(object[])).UdonType;
     }
 }
 public UdonSharpBehaviourTypeSymbol(IArrayTypeSymbol sourceSymbol, AbstractPhaseContext context)
     : base(sourceSymbol, context)
 {
     if (sourceSymbol.ElementType.TypeKind == TypeKind.Array)
     {
         UdonType = (ExternTypeSymbol)context.GetTypeSymbol(SpecialType.System_Object).MakeArrayType(context);
     }
     else
     {
         UdonType = (ExternTypeSymbol)context.GetTypeSymbol(typeof(Component[]));
     }
 }
 public ImportedUdonSharpTypeSymbol(INamedTypeSymbol sourceSymbol, AbstractPhaseContext context)
     : base(sourceSymbol, context)
 {
     if (sourceSymbol.TypeKind == TypeKind.Enum)
     {
         UdonType = context.GetTypeSymbol(sourceSymbol.EnumUnderlyingType).UdonType;
     }
     else
     {
         UdonType = context.GetTypeSymbol(typeof(object[])).UdonType;
     }
 }
Пример #8
0
        public ExternBuiltinOperatorSymbol(IMethodSymbol sourceSymbol, AbstractPhaseContext context)
            : base(sourceSymbol, context)
        {
            if (sourceSymbol.Parameters.Length == 1 &&
                (ContainingType == context.GetTypeSymbol(SpecialType.System_Byte) ||
                 ContainingType == context.GetTypeSymbol(SpecialType.System_SByte) ||
                 ContainingType == context.GetTypeSymbol(SpecialType.System_Int16) ||
                 ContainingType == context.GetTypeSymbol(SpecialType.System_UInt16)))
            {
                ReturnType = context.GetTypeSymbol(SpecialType.System_Int32);
            }

            OperatorType    = TranslateOperatorName(sourceSymbol.Name);
            ExternSignature = GetSignature(context);
        }
            private static MethodSymbol BuildMethod(AbstractPhaseContext context, MethodSymbol methodSymbol)
            {
                string methodName = methodSymbol.Name;
                string returnName;

                if (methodSymbol.ReturnType.IsArray)
                {
                    returnName = "__TArray";
                }
                else
                {
                    returnName = "__T";
                }

                string paramStr = "";

                if (methodSymbol.Parameters.Length > 0)
                {
                    paramStr = "__SystemBoolean";
                }

                string methodIdentifier = $"UnityEngineComponent.__{methodName}{paramStr}{returnName}";

                var roslynSymbol = methodSymbol.RoslynSymbol;

                return(new ExternSynthesizedMethodSymbol(context, methodIdentifier,
                                                         roslynSymbol.Parameters.Select(e => context.GetTypeSymbol(e.Type)).ToArray(),
                                                         context.GetTypeSymbol(roslynSymbol.ReturnType), false));
            }
Пример #10
0
        public ParameterSymbol(IParameterSymbol sourceSymbol, AbstractPhaseContext context)
            : base(sourceSymbol, context)
        {
            Type = context.GetTypeSymbol(RoslynSymbol.Type);

            if (RoslynSymbol.OriginalDefinition != RoslynSymbol)
            {
                OriginalSymbol = context.GetSymbol(RoslynSymbol.OriginalDefinition);
            }

            if (RoslynSymbol.HasExplicitDefaultValue)
            {
                if (Type.IsEnum)
                {
                    DefaultValue = (IConstantValue)Activator.CreateInstance(
                        typeof(ConstantValue <>).MakeGenericType(Type.UdonType.SystemType),
                        Enum.ToObject(Type.UdonType.SystemType, RoslynSymbol.ExplicitDefaultValue));
                }
                else
                {
                    DefaultValue = (IConstantValue)Activator.CreateInstance(
                        typeof(ConstantValue <>).MakeGenericType(Type.UdonType.SystemType),
                        RoslynSymbol.ExplicitDefaultValue);
                }
            }
        }
Пример #11
0
 public BoundShortCircuitOperatorExpression(BinaryExpressionSyntax node, BuiltinOperatorType operatorType, BoundExpression lhs, BoundExpression rhs, AbstractPhaseContext context)
     : base(node)
 {
     ValueType    = context.GetTypeSymbol(SpecialType.System_Boolean);
     Lhs          = lhs;
     Rhs          = rhs;
     OperatorType = operatorType;
 }
            private static PropertySymbol BuildProperty(AbstractPhaseContext context, BoundExpression sourceExpression)
            {
                TypeSymbol propertyType = sourceExpression.ValueType;

                if (propertyType.UdonType.ExternSignature == "VRCUdonUdonBehaviour")
                {
                    propertyType = context.GetTypeSymbol(typeof(IUdonEventReceiver));
                }

                TypeSymbol   boolType  = context.GetTypeSymbol(SpecialType.System_Boolean);
                MethodSymbol setMethod = new ExternSynthesizedMethodSymbol(context, "set_enabled", propertyType,
                                                                           new[] { boolType }, null, false);
                MethodSymbol getMethod = new ExternSynthesizedMethodSymbol(context, "get_enabled", propertyType,
                                                                           new TypeSymbol[] {}, boolType, false);

                return(new SynthesizedPropertySymbol(context, getMethod, setMethod));
            }
Пример #13
0
        protected Symbol(ISymbol sourceSymbol, AbstractPhaseContext context)
        {
            RoslynSymbol = sourceSymbol;

            if (sourceSymbol?.ContainingType != null && !(sourceSymbol is ITypeParameterSymbol))
            {
                ContainingType = context.GetTypeSymbol(sourceSymbol.ContainingType);
            }
        }
Пример #14
0
        private static bool TryCreateInstantiationInvocation(AbstractPhaseContext context, SyntaxNode node,
                                                             MethodSymbol symbol, BoundExpression instanceExpression, BoundExpression[] parameterExpressions,
                                                             out BoundInvocationExpression createdInvocation)
        {
            switch (symbol.Name)
            {
            case "Instantiate_Extern" when symbol.ContainingType == context.GetTypeSymbol(typeof(InstantiationShim)):
                createdInvocation = new BoundExternInvocation(node, context,
                                                              new ExternSynthesizedMethodSymbol(context,
                                                                                                "VRCInstantiate.__Instantiate__UnityEngineGameObject__UnityEngineGameObject",
                                                                                                parameterExpressions.Select(e => e.ValueType).ToArray(),
                                                                                                context.GetTypeSymbol(typeof(GameObject)), true),
                                                              instanceExpression, parameterExpressions);

                return(true);

            case "VRCInstantiate" when symbol.ContainingType == context.GetTypeSymbol(typeof(UdonSharpBehaviour)):     // Backwards compatibility for UdonSharpBehaviour.VRCInstantiate
            case "Instantiate" when symbol.ContainingType == context.GetTypeSymbol(typeof(UnityEngine.Object)):
            {
                if (symbol.Name != "VRCInstantiate" &&
                    (symbol.TypeArguments.Length != 1 ||
                     symbol.TypeArguments[0] != context.GetTypeSymbol(typeof(GameObject))))
                {
                    throw new NotSupportedException("Udon does not support instantiating non-GameObject types");
                }

                TypeSymbol   instantiateShim   = context.GetTypeSymbol(typeof(InstantiationShim));
                MethodSymbol instantiateMethod = instantiateShim.GetMembers <MethodSymbol>("Instantiate", context)
                                                 .First(e => e.Parameters
                                                        .Select(p => p.Type)
                                                        .SequenceEqual(parameterExpressions
                                                                       .Select(p => p.ValueType)));

                context.MarkSymbolReferenced(instantiateMethod);

                createdInvocation = new BoundStaticUserMethodInvocation(node, instantiateMethod, parameterExpressions);
                return(true);
            }
            }

            createdInvocation = null;
            return(false);
        }
Пример #15
0
        private static bool TryCreateBaseEnumMethodInvocation(AbstractPhaseContext context, SyntaxNode node,
                                                              MethodSymbol symbol, BoundExpression instanceExpression, BoundExpression[] parameterExpressions,
                                                              out BoundInvocationExpression createdInvocation)
        {
            if ((symbol.Name == "ToString" || symbol.Name == "GetHashCode" || symbol.Name == "Equals") &&
                symbol.ContainingType != null &&
                symbol.ContainingType == context.GetTypeSymbol(SpecialType.System_Enum))
            {
                createdInvocation = new BoundExternInvocation(node, context,
                                                              context.GetTypeSymbol(SpecialType.System_Object).GetMember <MethodSymbol>(symbol.Name, context),
                                                              instanceExpression,
                                                              parameterExpressions);

                return(true);
            }

            createdInvocation = null;
            return(false);
        }
Пример #16
0
        private static bool TryCreateArrayMethodInvocation(AbstractPhaseContext context, SyntaxNode node,
                                                           MethodSymbol symbol, BoundExpression instanceExpression, BoundExpression[] parameterExpressions,
                                                           out BoundInvocationExpression createdInvocation)
        {
            if ((symbol.Name == "IndexOf" || symbol.Name == "BinarySearch" || symbol.Name == "LastIndexOf" || symbol.Name == "Reverse") &&
                symbol.ContainingType == context.GetTypeSymbol(typeof(Array)))
            {
                MethodSymbol arrayMethod = context.GetTypeSymbol(typeof(Array))
                                           .GetMembers <MethodSymbol>(symbol.Name, context)
                                           .First(e => !e.RoslynSymbol.IsGenericMethod && e.Parameters.Length == symbol.Parameters.Length);

                createdInvocation = new BoundExternInvocation(node, context, arrayMethod, instanceExpression,
                                                              parameterExpressions);
                return(true);
            }

            createdInvocation = null;
            return(false);
        }
Пример #17
0
        /// <summary>
        /// Udon exposes a generic SetProgramVariable which the overload finding will attempt to use and fail to find,
        ///  so just use the non-generic version in this case
        /// </summary>
        private static bool TryCreateSetProgramVariableInvocation(AbstractPhaseContext context, SyntaxNode node,
                                                                  MethodSymbol symbol, BoundExpression instanceExpression, BoundExpression[] parameterExpressions,
                                                                  out BoundInvocationExpression createdInvocation)
        {
            if (symbol.Name == "SetProgramVariable" &&
                symbol.ContainingType == context.GetTypeSymbol(typeof(UdonBehaviour)))
            {
                MethodSymbol setProgramVarObjMethod = context.GetTypeSymbol(typeof(UdonBehaviour))
                                                      .GetMembers <MethodSymbol>("SetProgramVariable", context)
                                                      .First(e => !e.RoslynSymbol.IsGenericMethod);

                createdInvocation = new BoundExternInvocation(node, context, setProgramVarObjMethod, instanceExpression,
                                                              parameterExpressions);
                return(true);
            }

            createdInvocation = null;
            return(false);
        }
Пример #18
0
        private string GetSignature(AbstractPhaseContext context)
        {
            System.Type methodSourceType = ContainingType.UdonType.SystemType;

            methodSourceType = UdonSharpUtils.RemapBaseType(methodSourceType);

            if (methodSourceType == typeof(string) &&
                (Parameters[0].Type.UdonType.SystemType == typeof(object) ||
                 Parameters[1].Type.UdonType.SystemType == typeof(object)))
            {
                return("SystemString.__Concat__SystemObject_SystemObject__SystemString");
            }

            string functionNamespace = CompilerUdonInterface.SanitizeTypeName(methodSourceType.FullName ??
                                                                              methodSourceType.Namespace + methodSourceType.Name);

            string methodName = $"__{GetOperatorUdonName().Trim('_').TrimStart('.')}";
            var    parameters = RoslynSymbol.Parameters;

            string paramStr = "_";                                                                                  // Arg separator

            if (parameters.Length > 1 || methodName.Contains("UnaryMinus") || methodName.Contains("UnaryNegation")) // Binary operators
            {
                foreach (IParameterSymbol parameter in parameters)
                {
                    paramStr +=
                        $"_{CompilerUdonInterface.GetUdonTypeName(context.GetTypeSymbol(parameter.Type))}";
                }
            }
            else // Unary operators, we just use the regular binary operator internally and handle it in the bound operator
            {
                paramStr += $"_{CompilerUdonInterface.GetUdonTypeName(context.GetTypeSymbol(parameters[0].Type))}";
                paramStr += $"_{CompilerUdonInterface.GetUdonTypeName(context.GetTypeSymbol(parameters[0].Type))}";
            }

            string returnStr =
                $"__{CompilerUdonInterface.GetUdonTypeName(ReturnType)}";

            return($"{functionNamespace}.{methodName}{paramStr}{returnStr}");
        }
Пример #19
0
        void FindCandidateInvocationTypes(AbstractPhaseContext context, List <TypeSymbol> candidates, TypeSymbol ty)
        {
            foreach (var intf in ty.RoslynSymbol.AllInterfaces)
            {
                candidates.Add(context.GetTypeSymbol(intf));
            }

            while (ty != null)
            {
                candidates.Add(ty);
                ty = ty.BaseType;
            }
        }
Пример #20
0
            private static BoundExpression[] GetParameterExpressions(AbstractPhaseContext context, MethodSymbol symbol, BoundExpression[] parameters)
            {
                BoundExpression typeExpression = new BoundConstantExpression(
                    symbol.TypeArguments[0].UdonType.SystemType,
                    context.GetTypeSymbol(typeof(Type)));

                if (parameters == null || parameters.Length == 0)
                {
                    return new [] { typeExpression }
                }
                ;

                return(parameters.Concat(new [] { typeExpression }).ToArray());
            }
Пример #21
0
        protected PropertySymbol(IPropertySymbol sourceSymbol, AbstractPhaseContext context)
            : base(sourceSymbol, context)
        {
            if (sourceSymbol == null)
            {
                return;
            }

            Type           = context.GetTypeSymbol(sourceSymbol.Type);
            ContainingType = context.GetTypeSymbol(sourceSymbol.ContainingType);

            Parameters = sourceSymbol.Parameters.Select(p => (ParameterSymbol)context.GetSymbol(p))
                         .ToImmutableArray();

            if (sourceSymbol.GetMethod != null)
            {
                GetMethod = (MethodSymbol)context.GetSymbol(sourceSymbol.GetMethod);
            }
            if (sourceSymbol.SetMethod != null)
            {
                SetMethod = (MethodSymbol)context.GetSymbol(sourceSymbol.SetMethod);
            }
        }
        private static Symbol MakeMethodSymbol(IMethodSymbol methodSymbol, AbstractPhaseContext context)
        {
            if (methodSymbol.MethodKind == MethodKind.BuiltinOperator &&
                methodSymbol.Parameters.Length == 2 &&
                methodSymbol.Parameters[0].Type.TypeKind == TypeKind.Enum &&
                context.GetTypeSymbol(methodSymbol.ReturnType) == context.GetTypeSymbol(SpecialType.System_Boolean))
            {
                TypeSymbol parameterType = context.GetTypeSymbol(methodSymbol.Parameters[0].Type);

                BuiltinOperatorType operatorType;
                if (methodSymbol.Name == "op_Equality")
                {
                    operatorType = BuiltinOperatorType.Equality;
                }
                else
                {
                    operatorType = BuiltinOperatorType.Inequality;
                }

                return(new ExternSynthesizedOperatorSymbol(operatorType, parameterType.UdonType, context));
            }

            return(new ImportedUdonSharpMethodSymbol(methodSymbol, context));
        }
Пример #23
0
        private static PropertySymbol BuildProperty(AbstractPhaseContext context, BoundExpression sourceExpression)
        {
            TypeSymbol arrayType   = sourceExpression.ValueType;
            TypeSymbol elementType = arrayType.ElementType;

            Type systemType = arrayType.ElementType.UdonType.SystemType;

            if (systemType == typeof(UnityEngine.Object) ||
                systemType.IsSubclassOf(typeof(UnityEngine.Object)))
            {
                arrayType = context.GetTypeSymbol(SpecialType.System_Object).MakeArrayType(context);
            }

            string arrayTypeName        = CompilerUdonInterface.GetMethodTypeName(arrayType.UdonType);
            string arrayElementTypeName = CompilerUdonInterface.GetUdonTypeName(arrayType.UdonType.ElementType);

            TypeSymbol   intType   = context.GetTypeSymbol(SpecialType.System_Int32);
            MethodSymbol setMethod = new ExternSynthesizedMethodSymbol(context, $"{arrayTypeName}.__Set__SystemInt32_{arrayElementTypeName}__SystemVoid",
                                                                       new[] { intType, elementType }, null, false);
            MethodSymbol getMethod = new ExternSynthesizedMethodSymbol(context, $"{arrayTypeName}.__Get__SystemInt32__{arrayElementTypeName}",
                                                                       new[] { intType }, elementType, false);

            return(new SynthesizedPropertySymbol(context, getMethod, setMethod));
        }
            private static PropertySymbol BuildProperty(AbstractPhaseContext context, BoundExpression sourceExpression, PropertySymbol propertySymbol)
            {
                TypeSymbol propertyType = sourceExpression.ValueType;

                if (propertyType.UdonType.ExternSignature == "VRCUdonUdonBehaviour")
                {
                    propertyType = context.GetTypeSymbol(typeof(IUdonEventReceiver));
                }

                MethodSymbol setMethod = new ExternSynthesizedMethodSymbol(context, $"set_{propertySymbol.Name}", propertyType,
                                                                           new[] { propertySymbol.Type }, null, false);
                MethodSymbol getMethod = new ExternSynthesizedMethodSymbol(context, $"get_{propertySymbol.Name}", propertyType,
                                                                           new TypeSymbol[] {}, propertySymbol.Type, false);

                return(new SynthesizedPropertySymbol(context, getMethod, setMethod));
            }
Пример #25
0
        private static bool TryCreateCompareToInvocation(AbstractPhaseContext context, SyntaxNode node,
                                                         MethodSymbol symbol, BoundExpression instanceExpression, BoundExpression[] parameterExpressions,
                                                         out BoundInvocationExpression createdInvocation)
        {
            if (symbol.Name == "CompareTo" &&
                symbol.ContainingType != null &&
                symbol.ContainingType == context.GetTypeSymbol(typeof(IComparable)))
            {
                createdInvocation = new BoundExternInvocation(node, context,
                                                              new ExternSynthesizedMethodSymbol(context, "CompareTo", instanceExpression.ValueType,
                                                                                                new [] { instanceExpression.ValueType },
                                                                                                context.GetTypeSymbol(SpecialType.System_Int32), false),
                                                              instanceExpression, parameterExpressions);

                return(true);
            }

            createdInvocation = null;
            return(false);
        }
Пример #26
0
        private static bool TryCreateUdonSharpMetadataInvocation(AbstractPhaseContext context, SyntaxNode node,
                                                                 MethodSymbol symbol, BoundExpression instanceExpression,
                                                                 out BoundInvocationExpression createdInvocation)
        {
            if (symbol.Name == "GetUdonTypeID" || symbol.Name == "GetUdonTypeName")
            {
                if (symbol.IsStatic &&
                    symbol.TypeArguments.Length == 1 &&
                    symbol.ContainingType == context.GetTypeSymbol(typeof(UdonSharpBehaviour)))
                {
                    IConstantValue constantValue;
                    TypeSymbol     constantType;

                    var typeArgs = symbol.TypeArguments.Select(e => context.GetTypeSymbol(e.RoslynSymbol)).ToArray();

                    if (symbol.Name == "GetUdonTypeID")
                    {
                        constantValue = new ConstantValue <long>(UdonSharpInternalUtility.GetTypeID(TypeSymbol.GetFullTypeName(typeArgs[0].RoslynSymbol)));
                        constantType  = context.GetTypeSymbol(SpecialType.System_Int64);
                    }
                    else
                    {
                        constantValue = new ConstantValue <string>(TypeSymbol.GetFullTypeName(typeArgs[0].RoslynSymbol));
                        constantType  = context.GetTypeSymbol(SpecialType.System_String);
                    }

                    createdInvocation = new BoundConstantInvocationExpression(node, constantValue, constantType);

                    return(true);
                }

                if (!symbol.IsStatic &&
                    instanceExpression != null &&
                    symbol.ContainingType == context.GetTypeSymbol(typeof(UdonSharpBehaviour)))
                {
                    TypeSymbol methodContainer = context.GetTypeSymbol(typeof(UdonSharpBehaviourMethods));
                    var        shimMethod      = methodContainer.GetMember <MethodSymbol>(symbol.Name, context);
                    context.MarkSymbolReferenced(shimMethod);

                    createdInvocation = CreateBoundInvocation(context, node, shimMethod, null, new [] { instanceExpression });

                    return(true);
                }
            }

            createdInvocation = null;
            return(false);
        }
Пример #27
0
 public ExternFieldSymbol(IFieldSymbol sourceSymbol, AbstractPhaseContext context)
     : base(sourceSymbol, context)
 {
     Type = context.GetTypeSymbol(sourceSymbol.Type);
 }
Пример #28
0
        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);
        }
Пример #29
0
 protected FieldSymbol(IFieldSymbol sourceSymbol, AbstractPhaseContext bindContext)
     : base(sourceSymbol, bindContext)
 {
     ContainingType = bindContext.GetTypeSymbol(sourceSymbol.ContainingType);
     Type           = bindContext.GetTypeSymbol(RoslynSymbol.Type);
 }
Пример #30
0
        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();
        }