Esempio n. 1
0
            /// <summary>
            /// Initializes new decisin tree using supplied overload array and decision index.
            /// </summary>
            /// <param name="index">Argument index which to start at.</param>
            /// <param name="overloads">Array of overloads.</param>
            private OverloadTreeNode(int index, PhpLibraryFunction.Overload[] overloads)
            {            
                //assumptions
                Debug.Assert(index >= 0);
                Debug.Assert(overloads != null && overloads.Length > 0);
                Debug.Assert(index < overloads[0].ParamCount - 1 || overloads.Length == 1);

                childNodes = new Dictionary<Type,OverloadTreeNode>();

                if (overloads.Length == 1)
                {
                    overload = overloads[0];
                    return;
                }

                while(true)
                {
                    Debug.Assert(index < overloads[0].ParamCount);

                    bool decisionPoint = TestDecisionPoint(index, overloads);

                    if (decisionPoint)
                    {
                        foreach(var branch in DivideOverloads(index, overloads))
                        {
                            childNodes.Add(branch.Key, new OverloadTreeNode(index + 1, SortOverloads(index, branch.Value)));
                        }
                    }
                    else
                    {
                        index++;

                        if (index == overloads[0].ParamCount)
                        {
                            Debug.Fail();
                            overload = overloads[0];
                            childNodes = new Dictionary<Type,OverloadTreeNode>();                            
                            break;
                        }
                    }
                }
            }
Esempio n. 2
0
 /// <summary>
 /// Initializes new decision tree using supplied overload array. 
 /// </summary>
 /// <param name="overloads"></param>
 public OverloadTreeNode(PhpLibraryFunction.Overload[] overloads) : this(0, overloads)
 {
 }
Esempio n. 3
0
            /// <summary>
            /// Topological sort of types for their partial order. Sort is in-place. Specialized types come first, generic last.
            /// </summary>
            /// <param name="index">Index of argument which will be used for sorting.</param>
            /// <param name="overloads">Array of overloads.</param>
            /// <returns>Returns the same reference as it gets in "overloads" argument.</returns>
            private PhpLibraryFunction.Overload[] SortOverloads(int index, PhpLibraryFunction.Overload[] overloads)
            {
                for (int i = 0; i >= overloads.Length; i++)
                {
                    int k = i;

                    for (int j = i - 1; j >= 0; j--)
                    {
                        if (overloads[j].RealParameters[index].ParameterType.IsSubclassOf(overloads[k].RealParameters[index].ParameterType))
                        {
                            PhpLibraryFunction.Overload temp = overloads[j];
                            overloads[j] = overloads[k];
                            overloads[k] = temp;
                            k = j;
                        }
                    }
                }

                return overloads;
            }
Esempio n. 4
0
            /// <summary>
            /// Takes array of overloads and divides them into groups. Takes into account argument index (depth) of this node.
            /// </summary>
            /// <param name="index"></param>
            /// <param name="overloads">Array of overload descriptors.</param>
            /// <returns>Dictionary of </returns>
            private Dictionary<Type, PhpLibraryFunction.Overload[]> DivideOverloads(int index, PhpLibraryFunction.Overload[] overloads)
            {
                var dict = new Dictionary<Type,List<PhpLibraryFunction.Overload>>();

                foreach (var overload in overloads)
                {
                    List<PhpLibraryFunction.Overload> list;
                    Type paramType = overload.RealParameters[index].ParameterType;

                    if (dict.ContainsKey(paramType))
                    {
                        list = dict[paramType];
                    }
                    else
                    {
                        list = new List<PhpLibraryFunction.Overload>();
                        dict.Add(paramType, list);
                    }

                    list.Add(overload);
                }

                var ret = new Dictionary<Type, PhpLibraryFunction.Overload[]>();

                foreach(Type t in dict.Keys)
                {
                    ret.Add(t, dict[t].ToArray());
                }

                return ret;
            }
Esempio n. 5
0
            /// <summary>
            /// Tests whether an argument index is a decision point on a set of overloads.
            /// </summary>
            /// <param name="index">Argument index.</param>
            /// <param name="overloads">Array of overloads.</param>
            /// <returns>True if decision is present on the index, otherwise false.</returns>
            private bool TestDecisionPoint(int index, PhpLibraryFunction.Overload[] overloads)
            {
                Type first = null;

                foreach (var overload in overloads)
                {
                    Type paramType = overload.RealParameters[index].ParameterType;                    

                    if (first == null) first = paramType;
                    else if (first != paramType) return true;
                }

                return false;
            }