예제 #1
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);
            }
        }
예제 #2
0
 public InvocationListElement(IList elements, IServiceProvider services)
 {
     this.HandleFirstElement(elements, services);
     LinkElements(elements);
     Resolve(elements, services);
     MyTail = elements[elements.Count - 1] as MemberElement;
 }
예제 #3
0
        // 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];
        }
예제 #4
0
 public void Link(MemberElement nextElement)
 {
     MyNext = nextElement;
     if ((nextElement != null))
     {
         nextElement.MyPrevious = this;
     }
 }
예제 #5
0
 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);
     }
 }
예제 #6
0
 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);
     }
 }
예제 #7
0
        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);
            }
        }
예제 #8
0
        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);
        }
예제 #9
0
 // 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);
     }
 }
예제 #10
0
        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);
        }
예제 #11
0
        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);
        }
예제 #12
0
        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);
            }
        }
예제 #13
0
 protected static bool IsElementPublic(MemberElement e)
 {
     return(e.IsPublic);
 }
예제 #14
0
 public bool IsAccessible(MemberElement owner)
 {
     return(owner.IsMemberAccessible(MyTarget));
 }