Example #1
0
        public void WriteCastOp(CastOp s, ExpressionUsage u)
        {
            switch (s.CastType)
            {
            default:
                WriteCast(s.Source, s.ReturnType, s.Operand, u);
                break;

            case CastType.Up:
                WriteUpCast(s.Source, s.ReturnType, s.Operand, u);
                break;

            case CastType.Down:
                WriteDownCast(s.Source, s.ReturnType, s.Operand, u);
                break;

            case CastType.Box:
                WriteBox(s.Source, s.ReturnType, s.Operand, false, u);
                break;

            case CastType.Unbox:
                WriteUnbox(s.Source, s.ReturnType, s.Operand, u);
                break;
            }
        }
Example #2
0
        public static bool TryTransformEnumHasFlagToIntOps(this CallMethod s, Log log, ref Expression result)
        {
            // Enum.HasFlag() -> (((int)a & (int)b) == (int)b)
            if (s.Method.DeclaringType is EnumType && s.Method.UnoName == "HasFlag" && s.Arguments.Length == 1)
            {
                var bt = s.Method.DeclaringType.Base;

                foreach (var o in bt.Operators)
                {
                    if (o.UnoName == "op_BitwiseAnd")
                    {
                        var a = new CastOp(s.Source, bt, s.Object.ActualValue);
                        var b = new CastOp(s.Source, bt, s.Arguments[0]);

                        foreach (var p in bt.Operators)
                        {
                            if (p.UnoName == "op_Equality")
                            {
                                result = new CallBinOp(s.Source, p, new CallBinOp(s.Source, o, a, b), b);
                                return(true);
                            }
                        }

                        log.Error(s.Source, ErrorCode.I0069, "'" + bt + ".op_Equality(" + bt + "," + bt + ")' was not found");
                        return(false);
                    }
                }

                log.Error(s.Source, ErrorCode.I0069, "'" + bt + ".op_BitwiseAnd(" + bt + "," + bt + ")' was not found");
            }

            return(false);
        }
Example #3
0
        public static bool TryTransformEnumUnOpToIntUnOp(this CallUnOp s, Log log, ref Expression result)
        {
            // Enum.UnOps -> Int.UnOps
            if (s.Operator.DeclaringType is EnumType)
            {
                var bt = s.Operator.DeclaringType.Base;

                foreach (var o in bt.Operators)
                {
                    if (o.UnoName == s.Operator.UnoName)
                    {
                        result = new CallUnOp(s.Source, o,
                                              new CastOp(s.Source, bt, s.Operand));

                        if (s.ReturnType == s.Operator.DeclaringType)
                        {
                            result = new CastOp(s.Source, s.Operator.DeclaringType, result);
                        }

                        return(true);
                    }
                }

                log.Error(s.Source, ErrorCode.I0071, "'" + bt + "." + s.Operator.UnoName + "(" + bt + ")' was not found");
            }

            return(false);
        }
Example #4
0
        public static bool TryTransformDelegateBinOp(this CallBinOp s, ILFactory ilf, ref Expression result)
        {
            DataType dt = s.Operator.DeclaringType;

            if (dt is DelegateType)
            {
                if (s.Operator.Symbol == "+")
                {
                    result = new CastOp(s.Source, dt, ilf.CallMethod(s.Source, dt, "Combine", s.Left, s.Right));
                    return(true);
                }
                if (s.Operator.Symbol == "-")
                {
                    result = new CastOp(s.Source, dt, ilf.CallMethod(s.Source, dt, "Remove", s.Left, s.Right));
                    return(true);
                }
            }

            return(false);
        }
 private Node RewriteAsCastToUnderlyingType(md.PrimitiveType underlyingType, CastOp op, Node n)
 {
     // if type of the argument and the underlying type match we can strip the Cast entirely
     if (underlyingType.PrimitiveTypeKind
         == ((md.PrimitiveType)n.Child0.Op.Type.EdmType).PrimitiveTypeKind)
     {
         return n.Child0;
     }
     else
     {
         return m_command.CreateNode(m_command.CreateCastOp(md.TypeUsage.Create(underlyingType, op.Type.Facets)), n.Child0);
     }
 }
        public override Node Visit(CastOp op, Node n)
        {
            // Visit children first to get rid of all the nominal types (including enums) in the subtree. 
            VisitChildren(n);

            // if casting to enum (e.g. (Color)3) - get rid of the cast if underlying type of the enum is the same
            // as the type of the cast argument. If they are not the same rewrite the cast so that the argument 
            // is casted to the underlying enum type. 
            if (md.TypeSemantics.IsEnumerationType(op.Type))
            {
                // We visited subtree so the result type of the cast argument should be now primitive even if it originally was not (e.g. enum). 
                PlanCompiler.Assert(md.TypeSemantics.IsPrimitiveType(n.Child0.Op.Type), "Primitive type expected.");
                var underlyingType = md.Helper.GetUnderlyingEdmTypeForEnumType(op.Type.EdmType);
                return RewriteAsCastToUnderlyingType(underlyingType, op, n);
            }
            if (md.TypeSemantics.IsSpatialType(op.Type))
            {
                // We visited subtree so the result type of the cast argument should now be a union spatial type even if it was originally strong). 
                PlanCompiler.Assert(
                    md.TypeSemantics.IsPrimitiveType(n.Child0.Op.Type, md.PrimitiveTypeKind.Geography)
                    || md.TypeSemantics.IsPrimitiveType(n.Child0.Op.Type, md.PrimitiveTypeKind.Geometry), "Union spatial type expected.");
                var underlyingType = md.Helper.GetSpatialNormalizedPrimitiveType(op.Type.EdmType);
                return RewriteAsCastToUnderlyingType(underlyingType, op, n);
            }

            // children visited so it's OK just to return the node
            return n;
        }
Example #7
0
 /// <summary>
 /// Copies a CastOp
 /// </summary>
 /// <param name="op">The Op to Copy</param>
 /// <param name="n">The Node that references the Op</param>
 /// <returns>A copy of the original Node that references a copy of the original Op</returns>
 public override Node Visit(CastOp op, Node n)
 {
     return(CopyDefault(m_destCmd.CreateCastOp(op.Type), n));
 }
 /// <summary>
 ///     Visitor pattern method for CastOp
 /// </summary>
 /// <param name="op"> The CastOp being visited </param>
 /// <param name="n"> The Node that references the Op </param>
 public virtual void Visit(CastOp op, Node n)
 {
     VisitScalarOpDefault(op, n);
 }
Example #9
0
 // <summary>
 // Copies a CastOp
 // </summary>
 // <param name="op"> The Op to Copy </param>
 // <param name="n"> The Node that references the Op </param>
 // <returns> A copy of the original Node that references a copy of the original Op </returns>
 public override Node Visit(CastOp op, Node n)
 {
     return CopyDefault(m_destCmd.CreateCastOp(op.Type), n);
 }