Ejemplo n.º 1
0
        public static void Go(OutputWriter writer, CastExpressionSyntax expression)
        {
            var symbol = TypeProcessor.GetSymbolInfo(expression);

            var castingFrom = TypeProcessor.GetTypeInfo(expression.Expression).Type ??
                              TypeProcessor.GetTypeInfo(expression).Type;

            var srcTypeDlang  = TypeProcessor.ConvertType(castingFrom);
            var destType      = TypeProcessor.GetTypeInfo(expression.Type).Type;
            var destTypeDlang = TypeProcessor.TryConvertType(expression.Type);

            if (destTypeDlang == srcTypeDlang)
            {
                Core.Write(writer, expression.Expression);
            }
            else
            //if (symbol.Symbol != null)// && srcTypeCpp != "int" && srcTypeCpp != "System.String" && srcTypeCpp != "bool")
            {
//                if (castingFrom != destType) // Check for implicit first then explicit

                bool useType = true;

                //We should start with exact converters and then move to more generic convertors i.e. base class or integers which are implicitly convertible
                var correctConverter = destType.GetImplicitCoversionOp(destType, castingFrom, true);
                //                            initializerType.Type.GetMembers("op_Implicit").OfType<IMethodSymbol>().FirstOrDefault(h => h.ReturnType == initializerType.Type && h.Parameters[0].Type == initializerType.ConvertedType);

                if (correctConverter == null)
                {
                    useType          = false;
                    correctConverter =
                        castingFrom.GetImplicitCoversionOp(destType, castingFrom, true);
                    //.GetMembers("op_Implicit").OfType<IMethodSymbol>().FirstOrDefault(h => h.ReturnType == initializerType.Type && h.Parameters[0].Type == initializerType.ConvertedType);
                }

                if (correctConverter != null)
                {
                    //                            Core.Write(writer, expression.Left);
                    //                            writer.Write(" = ");
                    if (correctConverter.ReturnType != destType)
                    {
                        writer.Write("Cast!(" + destTypeDlang + (destType.IsValueType ? "" : "") + ")(");
                    }

                    if (castingFrom.SpecialType == SpecialType.System_Decimal && destType.IsPrimitiveInteger())
                    {
                    }
                    else
                    {
                        if (useType)
                        {
                            writer.Write(TypeProcessor.ConvertType(destType) + "." + "op_Implicit_" +
                                         TypeProcessor.ConvertType(correctConverter.ReturnType, false, true, false).Replace(".", "_"));
                        }
                        else
                        {
                            writer.Write(TypeProcessor.ConvertType(castingFrom) + "." + "op_Implicit_" +
                                         TypeProcessor.ConvertType(correctConverter.ReturnType, false, true, false).Replace(".", "_"));
                        }
                    }
                    writer.Write("(");
                    Core.Write(writer, expression.Expression);
                    writer.Write(")");

                    if (correctConverter.ReturnType != destType)
                    {
                        writer.Write(")");
                    }

                    return;
                }

                useType = true;

                //We should start with exact converters and then move to more generic convertors i.e. base class or integers which are implicitly convertible
                correctConverter = destType.GetExplictCoversionOp(destType, castingFrom, true);
                //                            initializerType.Type.GetMembers("op_Implicit").OfType<IMethodSymbol>().FirstOrDefault(h => h.ReturnType == initializerType.Type && h.Parameters[0].Type == initializerType.ConvertedType);

                if (correctConverter == null)
                {
                    useType          = false;
                    correctConverter =
                        castingFrom.GetExplictCoversionOp(destType, castingFrom, true);
                    //.GetMembers("op_Implicit").OfType<IMethodSymbol>().FirstOrDefault(h => h.ReturnType == initializerType.Type && h.Parameters[0].Type == initializerType.ConvertedType);
                }

                if (correctConverter != null)
                {
                    var iscast = correctConverter.ReturnType != destType;
                    if (iscast)
                    {
                        writer.Write("Cast!(" + destTypeDlang + ")(");
                    }

                    //                            Core.Write(writer, expression.Left);
                    //                            writer.Write(" = ");

                    if (castingFrom.SpecialType == SpecialType.System_Decimal && destType.IsPrimitiveInteger())
                    {
                    }
                    else
                    {
                        if (useType)
                        {
                            writer.Write(TypeProcessor.ConvertType(destType) + "." + "op_Explicit");
                        }
                        else
                        {
                            writer.Write(TypeProcessor.ConvertType(castingFrom) + "." + "op_Explicit");
                        }
                    }

                    writer.Write("(");
                    Core.Write(writer, expression.Expression);
                    writer.Write(")");
                    if (iscast)
                    {
                        writer.Write(")");
                    }
                    return;
                }

                if (TypeProcessor.IsPrimitiveType(srcTypeDlang) && TypeProcessor.IsPrimitiveType(destTypeDlang))
                {//primitives can be directly cast
                    writer.Write("cast(" + destTypeDlang + ")");
                    Core.Write(writer, expression.Expression);
                }

                else
                {
                    var convertedType = TypeProcessor.GetTypeInfo(expression).Type;
                    var type          = TypeProcessor.GetTypeInfo(expression.Expression).Type;

                    if (type.IsValueType && !convertedType.IsValueType)
                    {
                        //We have to box then cast if not Object
                        if (destType.Name != "Object")
                        {
                            writer.Write("Cast!(" + destTypeDlang + ")(");
                        }
                        //Box
                        writer.Write("BOX!(" + TypeProcessor.ConvertType(type) + ")(");
                        //When passing an argument by ref or out, leave off the .Value suffix
//                    writer.Write(" >(");
                        Core.Write(writer, expression.Expression);
                        writer.Write(")");
                        if (destType.Name != "Object")
                        {
                            writer.Write(")");
                        }
                    }
                    else if (!type.IsValueType && convertedType.IsValueType)
                    {
                        //UnBox
                        //					writer.Write("(Cast!( Boxed!(" + TypeProcessor.ConvertType(convertedType) + ") )(");
                        //                    Core.Write(writer, expression.Expression);
                        //					writer.Write(")).Value");

                        writer.Write("UNBOX!(" + TypeProcessor.ConvertType(convertedType) + ")(");
                        Core.Write(writer, expression.Expression);
                        writer.Write(")");
                    }
                    else if (type.IsValueType && convertedType.IsValueType)
                    {
                        if (convertedType.TypeKind == TypeKind.Pointer)
                        {
                            //cannot use ascast here, its for boxed types and objects
                            writer.Write("cast(" + destTypeDlang + (destType.IsValueType ? "" : "") + ")(");
                            Core.Write(writer, expression.Expression);
                            writer.Write(")");
                        }
                        else
                        {
                            //cannot use ascast here, its for boxed types and objects
                            writer.Write("Cast!(" + destTypeDlang + (destType.IsValueType ? "" : "") + ")(");
                            Core.Write(writer, expression.Expression);
                            writer.Write(")");
                        }
                    }
                    else
                    {
                        writer.Write("Cast!(");
                        writer.Write(destTypeDlang);
                        writer.Write(")(");
                        Core.Write(writer, expression.Expression);
                        writer.Write(")");
                    }
                }
            }
        }