Beispiel #1
0
        internal override void WriteTo(CCodeWriterBase c)
        {
            var interfaceCastRequired = this.ConversionKind == ConversionKind.Boxing && Type.TypeKind == TypeKind.Interface;

            if (interfaceCastRequired)
            {
                c.TextSpan(this.TypeSource.AllInterfaces.Contains((INamedTypeSymbol)Type) ? "interface_cast" : "dynamic_interface_cast_or_throw");
                c.TextSpan("<");
                c.WriteType(Type);
                c.TextSpan(">");
                c.TextSpan("(");
            }

            var effectiveExpression = this.Operand;

            if ((this.ConversionKind == ConversionKind.Boxing || this.ConversionKind == ConversionKind.ImplicitReference) &&
                this.Operand.IsStaticOrSupportedVolatileWrapperCall())
            {
                effectiveExpression = new Cast
                {
                    Type    = this.TypeSource,
                    Operand = effectiveExpression,
                    CCast   = true,
                    UseEnumUnderlyingType = true,
                };
            }

            if (this.ConversionKind == ConversionKind.Unboxing && this.Operand.Type.TypeKind == TypeKind.Interface)
            {
                effectiveExpression = new Conversion
                {
                    Type = new NamedTypeImpl {
                        SpecialType = SpecialType.System_Object
                    },
                    TypeSource     = this.TypeSource,
                    Operand        = effectiveExpression,
                    ConversionKind = ConversionKind.ImplicitReference
                };
            }

            var parenthesis = false;

            if (this.WriteCast(c, out parenthesis))
            {
                if (parenthesis)
                {
                    c.WriteExpressionInParenthesesIfNeeded(effectiveExpression);
                }
                else
                {
                    c.TextSpan("(");
                    if (this.ConversionKind == ConversionKind.Boxing && Cs2CGenerator.DebugOutput)
                    {
                        c.TextSpan("__FILE__, __LINE__, ");
                    }

                    effectiveExpression.WriteTo(c);
                    c.TextSpan(")");
                }
            }

            if (interfaceCastRequired)
            {
                c.TextSpan(")");
            }
        }
Beispiel #2
0
        private static Expression PreprocessParameter(Expression expression, IParameterSymbol parameter, IMethodSymbol method, IMethodSymbol methodOwner = null)
        {
            if (parameter == null)
            {
                return(expression);
            }

            var parameterType = parameter.Type;

            if (parameterType == null)
            {
                return(expression);
            }

            var effectiveExpression = expression;

            var typeDestination = parameterType;

            if (typeDestination.IsReferenceType)
            {
                var literal = expression as Literal;
                if (literal != null && literal.Value.IsNull)
                {
                    effectiveExpression = new Conversion
                    {
                        Type        = typeDestination,
                        Operand     = effectiveExpression,
                        MethodOwner = methodOwner
                    };
                }
            }

            var thisRef = expression as ThisReference;

            if (typeDestination.IsValueType && thisRef != null && !thisRef.ValueAsReference)
            {
                effectiveExpression = new PointerIndirectionOperator
                {
                    Operand     = expression,
                    MethodOwner = methodOwner
                };
            }

            if (expression.IsStaticOrSupportedVolatileWrapperCall())
            {
                effectiveExpression = new Cast
                {
                    Type                  = typeDestination,
                    Operand               = effectiveExpression,
                    Reference             = parameter.RefKind.HasFlag(RefKind.Ref) || parameter.RefKind.HasFlag(RefKind.Out),
                    CCast                 = true,
                    UseEnumUnderlyingType = true,
                    MethodOwner           = methodOwner
                };
            }

            if (effectiveExpression.IsReference && (effectiveExpression.Type.TypeKind == TypeKind.Interface) &&
                parameter.Type.SpecialType == SpecialType.System_Object)
            {
                effectiveExpression = new Conversion
                {
                    ConversionKind = ConversionKind.ImplicitReference,
                    IsReference    = true,
                    Operand        = expression,
                    TypeSource     = effectiveExpression.Type,
                    Type           = parameter.Type,
                    MethodOwner    = methodOwner
                };
            }

            // to support virtual generics it is required to sync. types
            if (method != null && method.IsVirtualGenericMethod())
            {
                var namedTypeImpl = GetTypeForVirtualGenericMethod(parameter, method);

                effectiveExpression = new Cast
                {
                    Type                  = namedTypeImpl,
                    Operand               = effectiveExpression,
                    Reference             = parameter.RefKind.HasFlag(RefKind.Ref) || parameter.RefKind.HasFlag(RefKind.Out),
                    CCast                 = true,
                    UseEnumUnderlyingType = true,
                    MethodOwner           = methodOwner
                };
            }

            // to support anonymous types

            /*
             * if (method != null && method.ContainingType.IsAnonymousType() && parameter.Type.IsValueType)
             * {
             *  var namedTypeImpl = new TypeImpl { SpecialType = SpecialType.System_Object };
             *  effectiveExpression = new Conversion
             *  {
             *      Type = namedTypeImpl,
             *      ConversionKind = ConversionKind.Boxing,
             *      Operand = effectiveExpression,
             *  };
             * }
             */

            return(effectiveExpression);
        }
Beispiel #3
0
        private Expression PrepareMethodReceiver(Expression receiverOpt, IMethodSymbol methodSymbol)
        {
            var effectiveReceiverOpt = receiverOpt;

            if (effectiveReceiverOpt.Kind == Kinds.ThisReference &&
                methodSymbol.MethodKind == MethodKind.Constructor &&
                ((TypeSymbol)(MethodOwner.ContainingType)).ToKeyString() != ((TypeSymbol)methodSymbol.ContainingType).ToKeyString())
            {
                effectiveReceiverOpt = new BaseReference {
                    Type = this.Method.ContainingType, IsReference = true, MethodOwner = MethodOwner
                };
            }

            if (!effectiveReceiverOpt.IsReference &&
                (effectiveReceiverOpt.Type.IsPrimitiveValueType() || effectiveReceiverOpt.Type.TypeKind == TypeKind.Enum))
            {
                effectiveReceiverOpt = new ObjectCreationExpression {
                    Arguments = { receiverOpt }, Type = effectiveReceiverOpt.Type, MethodOwner = MethodOwner
                };
            }

            if (!effectiveReceiverOpt.IsReference &&
                effectiveReceiverOpt.Type.IsValueType &&
                !effectiveReceiverOpt.Type.IsPrimitiveValueType() &&
                methodSymbol.IsVirtualMethod() &&
                effectiveReceiverOpt is ArrayAccess)
            {
                effectiveReceiverOpt = new Cast
                {
                    Constrained = true,
                    Operand     = receiverOpt,
                    Type        = methodSymbol.ContainingType
                };
            }

            if (effectiveReceiverOpt.IsReference && (effectiveReceiverOpt.Type.TypeKind == TypeKind.Interface) && methodSymbol.ContainingType.SpecialType == SpecialType.System_Object)
            {
                effectiveReceiverOpt = new Conversion
                {
                    ConversionKind = ConversionKind.ImplicitReference,
                    IsReference    = true,
                    Operand        = receiverOpt,
                    TypeSource     = receiverOpt.Type,
                    Type           = methodSymbol.ContainingType,
                    MethodOwner    = MethodOwner
                };
            }

            if (effectiveReceiverOpt.Type.TypeKind == TypeKind.TypeParameter && this.Method.ReceiverType != effectiveReceiverOpt.Type)
            {
                ////var constrained = ((ITypeParameterSymbol)receiverOpt.Type).ConstraintTypes;
                ////foreach (var constrainedType in constrained)
                ////{
                ////    receiverOpt = new Cast
                ////    {
                ////        Constrained = true,
                ////        Operand = receiverOpt,
                ////        Type = constrainedType
                ////    };
                ////}
                effectiveReceiverOpt = new Cast
                {
                    Constrained = true,
                    Operand     = effectiveReceiverOpt,
                    Type        = this.Method.ReceiverType,
                    MethodOwner = MethodOwner
                };
            }

            if (effectiveReceiverOpt.Type.IsPrimitiveValueTypePointer() && this.Method.ReceiverType != effectiveReceiverOpt.Type)
            {
                effectiveReceiverOpt = new Cast
                {
                    Operand     = effectiveReceiverOpt,
                    Type        = this.Method.ReceiverType,
                    BoxByRef    = true,
                    IsReference = true,
                    MethodOwner = MethodOwner
                };
            }

            return(effectiveReceiverOpt);
        }
Beispiel #4
0
        private static Expression PreprocessParameter(Expression expression, IParameterSymbol parameter)
        {
            if (parameter == null)
            {
                return(expression);
            }

            var parameterType = parameter.Type;

            if (parameterType == null)
            {
                return(expression);
            }

            var effectiveExpression = expression;

            var typeDestination = parameterType;

            if (typeDestination.IsReferenceType)
            {
                var literal = expression as Literal;
                if (literal != null && literal.Value.IsNull)
                {
                    effectiveExpression = new Conversion
                    {
                        Type    = typeDestination,
                        Operand = effectiveExpression
                    };
                }
            }

            if (typeDestination.IsValueType && expression is ThisReference)
            {
                effectiveExpression = new PointerIndirectionOperator {
                    Operand = expression
                };
            }

            if (expression.IsStaticWrapperCall())
            {
                effectiveExpression = new Cast
                {
                    Type                  = typeDestination,
                    Operand               = effectiveExpression,
                    Reference             = parameter.RefKind.HasFlag(RefKind.Ref) || parameter.RefKind.HasFlag(RefKind.Out),
                    CCast                 = true,
                    UseEnumUnderlyingType = true,
                };
            }

            if (effectiveExpression.IsReference && (effectiveExpression.Type.TypeKind == TypeKind.Interface) && parameter.Type.SpecialType == SpecialType.System_Object)
            {
                effectiveExpression = new Conversion
                {
                    ConversionKind = ConversionKind.ImplicitReference,
                    IsReference    = true,
                    Operand        = expression,
                    TypeSource     = effectiveExpression.Type,
                    Type           = parameter.Type
                };
            }

            return(effectiveExpression);
        }