Exemple #1
0
 private ClassHierarchyNode FindGreatestCommonDescendant(ICollection <ClassHierarchyNode> typeNodes)
 {
     V_0 = null;
     V_1 = 0x7fffffff;
     V_2 = typeNodes.GetEnumerator();
     try
     {
         while (V_2.MoveNext())
         {
             V_3 = V_2.get_Current();
             V_4 = ExpressionTypeInferer.GetTypeIndex(V_3.get_NodeType());
             if (V_4 >= V_1)
             {
                 continue;
             }
             V_1 = V_4;
             V_0 = V_3;
         }
     }
     finally
     {
         if (V_2 != null)
         {
             V_2.Dispose();
         }
     }
     return(V_0);
 }
Exemple #2
0
 protected override ClassHierarchyNode FindLowestCommonAncestor(ICollection <ClassHierarchyNode> typeNodes)
 {
     V_0 = null;
     V_1 = -2147483648;
     V_2 = typeNodes.GetEnumerator();
     try
     {
         while (V_2.MoveNext())
         {
             V_3 = V_2.get_Current();
             V_4 = ExpressionTypeInferer.GetTypeIndex(V_3.get_NodeType());
             if (V_4 <= V_1)
             {
                 continue;
             }
             V_1 = V_4;
             V_0 = V_3;
         }
     }
     finally
     {
         if (V_2 != null)
         {
             V_2.Dispose();
         }
     }
     return(V_0);
 }
Exemple #3
0
 private bool IsAssignable(TypeReference toAssign, TypeReference recipient)
 {
     if (!toAssign.get_IsPrimitive() || !recipient.get_IsPrimitive())
     {
         return(true);
     }
     stackVariable6 = ExpressionTypeInferer.GetTypeIndex(toAssign);
     return(stackVariable6 + 1 == ExpressionTypeInferer.GetTypeIndex(recipient));
 }
        /// <summary>
        /// Checks if one primitive type is Directly smaller than the other.
        /// </summary>
        /// <param name="toAssign">The supposed smaller type.</param>
        /// <param name="recipient">The supposed bigger type.</param>
        /// <returns></returns>
        private bool IsAssignable(TypeReference toAssign, TypeReference recipient)
        {
            ///This method handles assignability between primitive types only.
            if (!toAssign.IsPrimitive || !recipient.IsPrimitive)
            {
                return(true);
            }
            int index  = ExpressionTypeInferer.GetTypeIndex(toAssign);
            int index2 = ExpressionTypeInferer.GetTypeIndex(recipient);

            return(index + 1 == index2);
        }
        /// <summary>
        /// As integer values can be ordered depending on their size, the graph algorithm used in TypeInferer isn't needed here.
        /// Instead, we might use the indexes to determine which is the smallest type big enough to contain every type provided in
        /// <paramref name="typeNodes"/>.
        /// </summary>
        /// <param name="typeNodes">The list of types.</param>
        /// <returns>The common parent node.</returns>
        protected override ClassHierarchyNode FindLowestCommonAncestor(ICollection <ClassHierarchyNode> typeNodes)
        {
            ClassHierarchyNode result = null;
            int maxIndex = Int32.MinValue;

            foreach (ClassHierarchyNode node in typeNodes)
            {
                int currentIndex = ExpressionTypeInferer.GetTypeIndex(node.NodeType);
                if (currentIndex > maxIndex)
                {
                    maxIndex = currentIndex;
                    result   = node;
                }
            }
            return(result);
        }
 internal static TypeReference GetContainingType(TypeDefinition leftType, TypeDefinition rightType)
 {
     if ((object)leftType == (object)rightType)
     {
         return(rightType);
     }
     if (leftType == null)
     {
         return(rightType);
     }
     if (rightType == null)
     {
         return(leftType);
     }
     if (ExpressionTypeInferer.GetTypeIndex(leftType) > ExpressionTypeInferer.GetTypeIndex(rightType))
     {
         return(leftType);
     }
     return(rightType);
 }
        /// <summary>
        /// Determines if the use of <paramref name="variable"/> in <paramref name="useExpression"/> requires a cast.
        /// </summary>
        /// <param name="useExpression">The expression being checked.</param>
        /// <param name="variable">The variable that might need to be casted.</param>
        private void AddCastIfNeeded(Expression useExpression, VariableReference variable)
        {
            switch (useExpression.CodeNodeType)
            {
            case CodeNodeType.MethodInvocationExpression:
                MethodInvocationExpression miEx = useExpression as MethodInvocationExpression;
                Expression argument             = miEx.Arguments.FirstOrDefault(x => x.CodeNodeType == CodeNodeType.VariableReferenceExpression &&
                                                                                (x as VariableReferenceExpression).Variable == variable);
                if (argument != null)
                {
                    ///The variable is passed as argument to the method.
                    int           argumentIndex = miEx.Arguments.IndexOf(argument);
                    TypeReference argumentType  = miEx.MethodExpression.Method.Parameters[argumentIndex].ResolveParameterType(miEx.MethodExpression.Method);
                    if (!IsSubtype(argumentType, variable.VariableType))
                    {
                        if (argumentType.IsPrimitive && variable.VariableType.IsPrimitive)
                        {
                            ///Integer values are not in inheritance relations. Some of them, however, can be expanded to bigger types
                            ///automatically, without the addition of a cast, i.e. Byte variable can be passed as int parameter without the
                            ///need to include a cast.
                            TypeReference containingType = ExpressionTypeInferer.GetContainingType(argumentType.Resolve(), variable.VariableType.Resolve());
                            if (containingType.FullName == argumentType.FullName)
                            {
                                ///Then the type of the argument contains the type of the variable, thus no cast is needed.
                                return;
                            }
                        }

                        ///Then a cast is needed.
                        miEx.Arguments[argumentIndex] = new CastExpression(argument, argumentType, null);
                        ///This should be enough to update the expression everywhere it is seen.
                    }
                }
                else
                {
                    /// Then the variable is the object from which the method is called
                    /// variable.SomeMethod(...);
                    Expression target = miEx.MethodExpression.Target;
                    if (target.CodeNodeType == CodeNodeType.VariableReferenceExpression && (target as VariableReferenceExpression).Variable == variable)
                    {
                        TypeReference targetType = miEx.MethodExpression.Method.DeclaringType;
                        if (!IsSubtype(targetType, variable.VariableType))
                        {
                            miEx.MethodExpression.Target = new CastExpression(target, targetType, null);
                        }
                    }
                    else
                    {
                        ///This should not be reachable, but anyway.
                        AddCastIfNeeded(target, variable);
                    }
                }
                break;

            case CodeNodeType.BinaryExpression:
                BinaryExpression binEx = useExpression as BinaryExpression;
                if (binEx.Operator == BinaryOperator.Assign)
                {
                    if (binEx.Right.CodeNodeType == CodeNodeType.VariableReferenceExpression &&
                        (binEx.Right as VariableReferenceExpression).Variable == variable)
                    {
                        TypeReference assignedAs = binEx.Left.ExpressionType;
                        ///binex.Right should be VariableReferenceExpression to 'variable'.
                        if (!IsSubtype(assignedAs, variable.VariableType))
                        {
                            binEx.Right = new CastExpression(binEx.Right, assignedAs, null);
                        }
                    }
                }
                break;
                //default:
                //throw new NotSupportedException("Not supported cast expression.");
            }
        }
        /// <summary>
        /// Finds the smallest type from the given types.
        /// </summary>
        /// <param name="typeNodes">The list of type nodes.</param>
        /// <returns>Returns the smallest type.</returns>
        private ClassHierarchyNode FindGreatestCommonDescendant(ICollection <ClassHierarchyNode> typeNodes)
        {
            ClassHierarchyNode result = null;
            int minIndex = Int32.MaxValue;

            foreach (ClassHierarchyNode node in typeNodes)
            {
                int currentIndex = ExpressionTypeInferer.GetTypeIndex(node.NodeType);
                if (currentIndex < minIndex)
                {
                    minIndex = currentIndex;
                    result   = node;
                }
            }
            return(result);

            //Stack<ClassHierarchyNode> possibleGcdOrdered = new Stack<ClassHierarchyNode>();
            //HashSet<ClassHierarchyNode> possibleGcdSearchable = new HashSet<ClassHierarchyNode>();
            //foreach (ClassHierarchyNode node in typeNodes)
            //{
            //    if (possibleGcdOrdered.Count == 0) //first pass
            //    {
            //        ClassHierarchyNode currentSubtype = node;
            //        while (currentSubtype != null)
            //        {
            //            possibleGcdOrdered.Push(currentSubtype);
            //            possibleGcdSearchable.Add(currentSubtype);
            //            ClassHierarchyNode nextSubtype = null;
            //            foreach (ClassHierarchyNode x in currentSubtype.SubTypes)
            //            {
            //                if (x.IsHardNode)
            //                {
            //                    nextSubtype = x;
            //                    break;
            //                }
            //            }
            //            currentSubtype = nextSubtype;
            //        }
            //    }
            //    else
            //    {
            //        ClassHierarchyNode firstSubtype = node;
            //        while (!possibleGcdSearchable.Contains(firstSubtype))
            //        {
            //            //should not reach null, as Int32 is the ultimate GCD
            //            ClassHierarchyNode nextSubtype = null;
            //            foreach (ClassHierarchyNode x in firstSubtype.SubTypes)
            //            {
            //                if (x.IsHardNode)
            //                {
            //                    nextSubtype = x;
            //                    break;
            //                }
            //            }
            //            firstSubtype = nextSubtype;
            //        }

            //        while (possibleGcdOrdered.Peek() != firstSubtype)
            //        {
            //            ClassHierarchyNode removed = possibleGcdOrdered.Pop();
            //            possibleGcdSearchable.Remove(removed);
            //        }
            //    }
            //}
            //return possibleGcdOrdered.Peek();
        }
 private void AddCastIfNeeded(Expression useExpression, VariableReference variable)
 {
     V_0          = new TypeInferer.u003cu003ec__DisplayClass8_0();
     V_0.variable = variable;
     V_4          = useExpression.get_CodeNodeType();
     if (V_4 == 19)
     {
         V_1 = useExpression as MethodInvocationExpression;
         V_2 = V_1.get_Arguments().FirstOrDefault <Expression>(new Func <Expression, bool>(V_0.u003cAddCastIfNeededu003eb__0));
         if (V_2 == null)
         {
             V_7 = V_1.get_MethodExpression().get_Target();
             if (V_7.get_CodeNodeType() != 26 || (object)(V_7 as VariableReferenceExpression).get_Variable() != (object)V_0.variable)
             {
                 this.AddCastIfNeeded(V_7, V_0.variable);
                 return;
             }
             V_8 = V_1.get_MethodExpression().get_Method().get_DeclaringType();
             if (!this.IsSubtype(V_8, V_0.variable.get_VariableType()))
             {
                 V_1.get_MethodExpression().set_Target(new ExplicitCastExpression(V_7, V_8, null));
                 return;
             }
         }
         else
         {
             V_5 = V_1.get_Arguments().IndexOf(V_2);
             V_6 = V_1.get_MethodExpression().get_Method().get_Parameters().get_Item(V_5).ResolveParameterType(V_1.get_MethodExpression().get_Method());
             if (!this.IsSubtype(V_6, V_0.variable.get_VariableType()))
             {
                 if (V_6.get_IsPrimitive() && V_0.variable.get_VariableType().get_IsPrimitive() && String.op_Equality(ExpressionTypeInferer.GetContainingType(V_6.Resolve(), V_0.variable.get_VariableType().Resolve()).get_FullName(), V_6.get_FullName()))
                 {
                     return;
                 }
                 V_1.get_Arguments().set_Item(V_5, new ExplicitCastExpression(V_2, V_6, null));
                 return;
             }
         }
     }
     else
     {
         if (V_4 != 24)
         {
             return;
         }
         V_3 = useExpression as BinaryExpression;
         if (V_3.get_Operator() == 26 && V_3.get_Right().get_CodeNodeType() == 26 && (object)(V_3.get_Right() as VariableReferenceExpression).get_Variable() == (object)V_0.variable)
         {
             V_9 = V_3.get_Left().get_ExpressionType();
             if (!this.IsSubtype(V_9, V_0.variable.get_VariableType()))
             {
                 V_3.set_Right(new ExplicitCastExpression(V_3.get_Right(), V_9, null));
             }
         }
     }
     return;
 }