/// <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; } } } }
/// <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); }