public InvocationListElement(IList elements, IServiceProvider services) { this.HandleFirstElement(elements, services); LinkElements(elements); Resolve(elements, services); MyTail = (MemberElement)elements[elements.Count - 1]; }
private bool ResolveFieldProperty(MemberElement previous) { var members = this.GetMembers(MemberTypes.Field | MemberTypes.Property); // Keep only the ones which are accessible members = this.GetAccessibleMembers(members); if (members.Length == 0) { // No accessible members; try to resolve a virtual property return this.ResolveVirtualProperty(previous); } else if (members.Length > 1) { // More than one accessible member if (previous == null) { base.ThrowCompileException(CompileErrorResourceKeys.IdentifierIsAmbiguous, CompileExceptionReason.AmbiguousMatch, MyName); } else { base.ThrowCompileException(CompileErrorResourceKeys.IdentifierIsAmbiguousOnType, CompileExceptionReason.AmbiguousMatch, MyName, previous.TargetType.Name); } } else { // Only one member; bind to it MyField = members[0] as FieldInfo; if ((MyField != null)) { return true; } // Assume it must be a property MyProperty = (PropertyInfo)members[0]; return true; } return false; }
public void Link(MemberElement nextElement) { MyNext = nextElement; if ((nextElement != null)) { nextElement.MyPrevious = this; } }
private void ThrowFunctionNotFoundException(MemberElement previous) { if (previous == null) { base.ThrowCompileException(CompileErrorResourceKeys.UndefinedFunction, CompileExceptionReason.UndefinedName, MyName, MyArguments); } else { base.ThrowCompileException(CompileErrorResourceKeys.UndefinedFunctionOnType, CompileExceptionReason.UndefinedName, MyName, MyArguments, previous.TargetType.Name); } }
protected static bool IsElementPublic(MemberElement e) { return e.IsPublic; }
private void AddReferencedVariable(MemberElement previous) { if ((previous != null)) { return; } if ((MyVariableType != null) || MyOptions.IsOwnerType(this.MemberOwnerType) == true) { ExpressionInfo info = (ExpressionInfo)MyServices.GetService(typeof(ExpressionInfo)); info.AddReferencedVariable(MyName); } }
private bool ResolveVirtualProperty(MemberElement previous) { if (previous == null) { // We can't use virtual properties if we are the first element return false; } var coll = TypeDescriptor.GetProperties(previous.ResultType); MyPropertyDescriptor = coll.Find(MyName, true); return (MyPropertyDescriptor != null); }
private void ThrowNoAccessibleMethodsException(MemberElement previous) { if (previous == null) { base.ThrowCompileException(CompileErrorResourceKeys.NoAccessibleMatches, CompileExceptionReason.AccessDenied, MyName, MyArguments); } else { base.ThrowCompileException(CompileErrorResourceKeys.NoAccessibleMatchesOnType, CompileExceptionReason.AccessDenied, MyName, MyArguments, previous.TargetType.Name); } }
// Find the best match from a set of overloaded methods private void ResolveOverloads(CustomMethodInfo[] infos, MemberElement previous, Type[] argTypes) { // Compute a score for each candidate foreach (CustomMethodInfo cmi in infos) { cmi.ComputeScore(argTypes); } // Sort array from best to worst matches Array.Sort<CustomMethodInfo>(infos); // Discard any matches that aren't accessible infos = this.GetAccessibleInfos(infos); // No accessible methods left if (infos.Length == 0) { this.ThrowNoAccessibleMethodsException(previous); } // Handle case where we have more than one match with the same score this.DetectAmbiguousMatches(infos); // If we get here, then there is only one best match MyTargetMethodInfo = infos[0]; }
// Try to find a match from a set of methods private void BindToMethod(ICollection<MethodInfo> methods, MemberElement previous, Type[] argTypes) { List<CustomMethodInfo> customInfos = new List<CustomMethodInfo>(); // Wrap the MethodInfos in our custom class foreach (MethodInfo mi in methods) { CustomMethodInfo cmi = new CustomMethodInfo(mi); customInfos.Add(cmi); } // Discard any methods that cannot qualify as overloads CustomMethodInfo[] arr = customInfos.ToArray(); customInfos.Clear(); foreach (CustomMethodInfo cmi in arr) { if (cmi.IsMatch(argTypes) == true) { customInfos.Add(cmi); } } if (customInfos.Count == 0) { // We have no methods that can qualify as overloads; throw exception this.ThrowFunctionNotFoundException(previous); } else { // At least one method matches our criteria; do our custom overload resolution this.ResolveOverloads(customInfos.ToArray(), previous, argTypes); } }