// 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); } }
public InvocationListElement(IList elements, IServiceProvider services) { this.HandleFirstElement(elements, services); LinkElements(elements); Resolve(elements, services); MyTail = elements[elements.Count - 1] as MemberElement; }
// 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]; }
public void Link(MemberElement nextElement) { MyNext = nextElement; if ((nextElement != null)) { nextElement.MyPrevious = this; } }
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); } }
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); } }
private void AddReferencedVariable(MemberElement previous) { if ((previous != null)) { return; } if ((MyVariableType != null) || MyOptions.IsOwnerType(this.MemberOwnerType) == true) { ExpressionInfo info = MyServices.GetService(typeof(ExpressionInfo)) as 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); } PropertyDescriptorCollection coll = TypeDescriptor.GetProperties(previous.ResultType); MyPropertyDescriptor = coll.Find(MyName, true); return(MyPropertyDescriptor != null); }
// Arrange elements as a linked list private static void LinkElements(IList elements) { for (int i = 0; i <= elements.Count - 1; i++) { MemberElement current = elements[i] as MemberElement; MemberElement nextElement = null; if (i + 1 < elements.Count) { nextElement = elements[i + 1] as MemberElement; } current.Link(nextElement); } }
public void EmitFunctionCall(bool nextRequiresAddress, FleeILGenerator ilg, IServiceProvider services) { ParameterInfo[] parameters = this.Method.GetParameters(); ExpressionElement[] elements = MyArguments.ToArray(); // Emit either a regular or paramArray call if (MyTargetMethodInfo.IsParamArray == false) { this.EmitRegularFunctionInternal(parameters, elements, ilg, services); } else { this.EmitParamArrayArguments(parameters, elements, ilg, services); } MemberElement.EmitMethodCall(this.ResultType, nextRequiresAddress, this.Method, ilg); }
private bool ResolveFieldProperty(MemberElement previous) { MemberInfo[] 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); }
private void ResolveNamespaces(IList elements, IServiceProvider services) { ExpressionContext context = services.GetService(typeof(ExpressionContext)) as ExpressionContext; ImportBase currentImport = context.Imports.RootImport; while (true) { string name = GetName(elements); if (name == null) { break; // TODO: might not be correct. Was : Exit While } ImportBase import = currentImport.FindImport(name); if (import == null) { break; // TODO: might not be correct. Was : Exit While } currentImport = import; elements.RemoveAt(0); if (elements.Count > 0) { MemberElement newFirst = (MemberElement)elements[0]; newFirst.SetImport(currentImport); } } if (elements.Count == 0) { base.ThrowCompileException(CompileErrorResourceKeys.NamespaceCannotBeUsedAsType, CompileExceptionReason.TypeMismatch, currentImport.Name); } }
protected static bool IsElementPublic(MemberElement e) { return(e.IsPublic); }
public bool IsAccessible(MemberElement owner) { return(owner.IsMemberAccessible(MyTarget)); }