예제 #1
1
        internal RubyOverloadGroupInfo(OverloadInfo/*!*/[]/*!*/ methods, RubyModule/*!*/ declaringModule,
            RubyOverloadGroupInfo/*!*/[] overloadOwners, bool isStatic)
            : base(methods, declaringModule, isStatic) {
            Debug.Assert(overloadOwners == null || methods.Length == overloadOwners.Length);

            _overloadOwners = overloadOwners;
        }
예제 #2
1
 protected RubyMethodGroupBase(OverloadInfo/*!*/[] methods, RubyMemberFlags flags, RubyModule/*!*/ declaringModule)
     : base(flags, declaringModule)
 {
     if (methods != null) {
         SetMethodBasesNoLock(methods);
     }
 }
예제 #3
0
        internal OverloadInfo/*!*/[]/*!*/ SetMethodBasesNoLock(OverloadInfo/*!*/[]/*!*/ methods) {
            Debug.Assert(
                CollectionUtils.TrueForAll(methods, (method) => method.IsStatic || method.DeclaringType == typeof(Object)) ||
                CollectionUtils.TrueForAll(methods, (method) => !method.IsStatic || method.IsExtension || RubyUtils.IsOperator(method))
            );

            return _methodBases = methods;
        }
예제 #4
0
        internal ParameterMapping(OverloadResolver resolver, OverloadInfo method, IList<string> argNames) {
            Assert.NotNull(resolver, method);
            _resolver = resolver;
            _overload = method;
            _argNames = argNames;
            _parameters = new List<ParameterWrapper>();
            _arguments = new List<ArgBuilder>(method.ParameterCount);
            _defaultArguments = new List<ArgBuilder>();
	    }
예제 #5
0
        public static bool ShouldWarn(PythonContext/*!*/ context, OverloadInfo/*!*/ method, out WarningInfo info) {
            Assert.NotNull(method);

            ObsoleteAttribute[] os = (ObsoleteAttribute[])method.ReflectionInfo.GetCustomAttributes(typeof(ObsoleteAttribute), true);
            if (os.Length > 0) {
                info = new WarningInfo(
                    PythonExceptions.DeprecationWarning,
                    String.Format("{0}.{1} has been obsoleted.  {2}",
                        NameConverter.GetTypeName(method.DeclaringType),
                        method.Name,
                        os[0].Message
                    )
                );

                return true;
            }

            if (context.PythonOptions.WarnPython30) {
                Python3WarningAttribute[] py3kwarnings = (Python3WarningAttribute[])method.ReflectionInfo.GetCustomAttributes(typeof(Python3WarningAttribute), true);
                if (py3kwarnings.Length > 0) {
                    info = new WarningInfo(
                        PythonExceptions.DeprecationWarning,
                        py3kwarnings[0].Message
                    );

                    return true;
                }
            }

#if !SILVERLIGHT
            // no apartment states on Silverlight
            if (method.DeclaringType == typeof(Thread)) {
                if (method.Name == "Sleep") {
                    info = new WarningInfo(
                        PythonExceptions.RuntimeWarning,
                        "Calling Thread.Sleep on an STA thread doesn't pump messages.  Use Thread.CurrentThread.Join instead.",
                        Expression.Equal(
                            Expression.Call(
                                Expression.Property(
                                    null,
                                    typeof(Thread).GetProperty("CurrentThread")
                                ),
                                typeof(Thread).GetMethod("GetApartmentState")
                            ),
                            AstUtils.Constant(ApartmentState.STA)
                        )
                    );

                    return true;
                }
            }
#endif

            info = null;
            return false;
        }
예제 #6
0
 internal ParameterMapping(OverloadResolver resolver, OverloadInfo method, IList <string> argNames)
 {
     Assert.NotNull(resolver, method);
     _resolver         = resolver;
     _overload         = method;
     _argNames         = argNames;
     _parameters       = new List <ParameterWrapper>();
     _arguments        = new List <ArgBuilder>(method.ParameterCount);
     _defaultArguments = new List <ArgBuilder>();
 }
예제 #7
0
 /// <summary>
 /// Gets the generic arguments for method based upon the constraints discovered during
 /// type inference.  Returns null if not all generic arguments had their types inferred.
 /// </summary>
 private static Type[] GetGenericArgumentsForInferedMethod(OverloadInfo target, Dictionary <Type, Type> constraints)
 {
     Type[] genArgs = ArrayUtils.MakeArray(target.GenericArguments);
     for (int i = 0; i < genArgs.Length; i++)
     {
         if (!constraints.TryGetValue(genArgs[i], out Type newType))
         {
             // we didn't discover any types for this type argument
             return(null);
         }
         genArgs[i] = newType;
     }
     return(genArgs);
 }
예제 #8
0
        internal MethodCandidate(OverloadResolver resolver, OverloadInfo method, List<ParameterWrapper> parameters, ParameterWrapper paramsDict,
            ReturnBuilder returnBuilder, InstanceBuilder instanceBuilder, IList<ArgBuilder> argBuilders, Dictionary<DynamicMetaObject, BindingRestrictions> restrictions) {

            Assert.NotNull(resolver, method, instanceBuilder, returnBuilder);
            Assert.NotNullItems(parameters);
            Assert.NotNullItems(argBuilders);

            _resolver = resolver;
            _overload = method;
            _instanceBuilder = instanceBuilder;
            _argBuilders = argBuilders;
            _returnBuilder = returnBuilder;
            _parameters = parameters;
            _paramsDict = paramsDict;
            _restrictions = restrictions;

            _paramsArrayIndex = ParameterWrapper.IndexOfParamsArray(parameters);

            parameters.TrimExcess();
        }
예제 #9
0
        internal MethodCandidate(OverloadResolver resolver, OverloadInfo method, List <ParameterWrapper> parameters, ParameterWrapper paramsDict,
                                 ReturnBuilder returnBuilder, InstanceBuilder instanceBuilder, IList <ArgBuilder> argBuilders, Dictionary <DynamicMetaObject, BindingRestrictions> restrictions)
        {
            Assert.NotNull(resolver, method, instanceBuilder, returnBuilder);
            Assert.NotNullItems(parameters);
            Assert.NotNullItems(argBuilders);

            Resolver         = resolver;
            Overload         = method;
            _instanceBuilder = instanceBuilder;
            ArgBuilders      = argBuilders;
            ReturnBuilder    = returnBuilder;
            _parameters      = parameters;
            _paramsDict      = paramsDict;
            Restrictions     = restrictions;

            ParamsArrayIndex = ParameterWrapper.IndexOfParamsArray(parameters);

            parameters.TrimExcess();
        }
예제 #10
0
        /// <summary>
        /// Builds a mapping based upon generic parameter constraints between related generic
        /// parameters.  This is then used to sort the generic parameters so that we can process
        /// the least dependent parameters first.  For example given the method:
        ///
        /// void Foo{T0, T1}(T0 x, T1 y) where T0 : T1
        ///
        /// We need to first infer the type information for T1 before we infer the type information
        /// for T0 so that we can ensure the constraints are correct.
        /// </summary>
        private static Dictionary <Type, List <Type> > GetDependencyMapping(OverloadInfo info)
        {
            Dictionary <Type, List <Type> > dependencies = new Dictionary <Type, List <Type> >();

            // need to calculate any dependencies between parameters.
            foreach (Type genArg in info.GenericArguments)
            {
                Type[] constraints = genArg.GetGenericParameterConstraints();
                foreach (Type t in constraints)
                {
                    if (t.IsGenericParameter)
                    {
                        AddDependency(dependencies, genArg, t);
                    }
                    else if (t.ContainsGenericParameters())
                    {
                        AddNestedDependencies(dependencies, genArg, t);
                    }
                }
            }
            return(dependencies);
        }
예제 #11
0
        /// <summary>
        /// Gets the generic type arguments sorted so that the type arguments
        /// that are depended upon by other type arguments are sorted before
        /// their dependencies.
        /// </summary>
        private static Type[] GetSortedGenericArguments(OverloadInfo info, Dictionary <Type, List <Type> > dependencies)
        {
            Type[] genArgs = ArrayUtils.MakeArray(info.GenericArguments);

            // Then sort the arguments based upon those dependencies
            Array.Sort(genArgs, (x, y) => {
                if (ReferenceEquals(x, y))
                {
                    return(0);
                }

                bool isDependent = IsDependentConstraint(dependencies, x, y);
                if (isDependent)
                {
                    return(1);
                }

                isDependent = IsDependentConstraint(dependencies, y, x);
                if (isDependent)
                {
                    return(-1);
                }

                int xhash = x.GetHashCode(), yhash = y.GetHashCode();
                if (xhash != yhash)
                {
                    return(xhash - yhash);
                }

                long idDiff = IdDispenser.GetId(x) - IdDispenser.GetId(y);
                return(idDiff > 0 ? 1 : -1);
            });


            return(genArgs);
        }
예제 #12
0
        internal static int GetHiddenParameterCount(OverloadInfo/*!*/ method, SelfCallConvention callConvention) {
            int i = 0;
            var infos = method.Parameters;

            if (callConvention == SelfCallConvention.SelfIsInstance) {
                if (method.IsStatic) {
                    Debug.Assert(RubyUtils.IsOperator(method) || method.IsExtension);
                    i++;
                }
            }

            while (i < infos.Count && infos[i].ParameterType.IsSubclassOf(typeof(RubyCallSiteStorage))) {
                i++;
            }

            if (i < infos.Count) {
                var info = infos[i];

                if (info.ParameterType == typeof(RubyScope)) {
                    i++;
                } else if (info.ParameterType == typeof(RubyContext)) {
                    i++;
                } else if (method.IsConstructor && info.ParameterType == typeof(RubyClass)) {
                    i++;
                }
            }

            if (i < infos.Count && infos[i].ParameterType == typeof(BlockParam)) {
                i++;
            }

            if (callConvention == SelfCallConvention.SelfIsParameter) {
                Debug.Assert(i < infos.Count);
                Debug.Assert(method.IsStatic);
                i++;
            }

            return i;
        }
예제 #13
0
 internal MethodCandidate ReplaceMethod(OverloadInfo newMethod, List<ParameterWrapper> parameters, IList<ArgBuilder> argBuilders, Dictionary<DynamicMetaObject, BindingRestrictions> restrictions) {
     return new MethodCandidate(_resolver, newMethod, parameters, _paramsDict, _returnBuilder, _instanceBuilder, argBuilders, restrictions);
 }
예제 #14
0
        private void AddBasicMethodTargets(OverloadInfo method) {
            Assert.NotNull(method);

            var mapping = new ParameterMapping(this, method, _argNames);

            mapping.MapParameters(false);

            foreach (var defaultCandidate in mapping.CreateDefaultCandidates()) {
                AddSimpleTarget(defaultCandidate);
            }

            // TODO: We reduce out/ref parameters only for the main overload.
            // We should rather treat all out params as optional (either a StrongBox is provided or not).
            var byRefReducedCandidate = mapping.CreateByRefReducedCandidate();
            if (byRefReducedCandidate != null) {
                AddSimpleTarget(byRefReducedCandidate);
            }

            AddSimpleTarget(mapping.CreateCandidate());
        }
예제 #15
0
        internal static MethodCandidate InferGenericMethod(ApplicableCandidate /*!*/ candidate, ActualArguments /*!*/ actualArgs)
        {
            OverloadInfo target = candidate.Method.Overload;

            Assert.NotNull(target);
            Debug.Assert(target.IsGenericMethodDefinition);
            Debug.Assert(target.IsGenericMethod && target.ContainsGenericParameters);

            List <DynamicMetaObject /*!*/> args = GetAllArguments(candidate, actualArgs);

            if (args == null)
            {
                return(null);
            }

            Dictionary <Type, List <Type> > dependencies = GetDependencyMapping(target);

            Type[] genArgs = GetSortedGenericArguments(target, dependencies);
            Dictionary <Type, ArgumentInputs> inputs = GetArgumentToInputMapping(candidate.Method, args);

            // now process the inputs
            var  binding      = new Dictionary <Type, Type>();
            var  restrictions = new Dictionary <DynamicMetaObject, BindingRestrictions>();
            bool noMethod     = false;

            foreach (Type t in genArgs)
            {
                if (!inputs.TryGetValue(t, out ArgumentInputs inps))
                {
                    continue;
                }

                Type bestType = inps.GetBestType(candidate.Method.Resolver, binding, restrictions);
                if (bestType == null)
                {
                    // we conflict with possible constraints
                    noMethod = true;
                    break;
                }
            }

            if (!noMethod)
            {
                // finally build a new MethodCandidate for the generic method
                genArgs = GetGenericArgumentsForInferedMethod(target, binding);
                if (genArgs == null)
                {
                    // not all types we're inferred
                    return(null);
                }

                OverloadInfo newMethod = target.MakeGenericMethod(genArgs);

                List <ParameterWrapper> newWrappers = CreateNewWrappers(candidate.Method, newMethod, target);

                List <ArgBuilder> argBuilders = CreateNewArgBuilders(candidate.Method, newMethod);
                if (argBuilders == null)
                {
                    // one or more arg builders don't support type inference
                    return(null);
                }

                if (restrictions.Count == 0)
                {
                    restrictions = null;
                }

                // create the new method candidate
                return(candidate.Method.ReplaceMethod(newMethod, newWrappers, argBuilders, restrictions));
            }

            return(null);
        }
예제 #16
0
        /// <summary>
        /// Creates a new list of ParameterWrappers for the generic method replacing the old parameters with the new ones.
        /// </summary>
        private static List <ParameterWrapper> CreateNewWrappers(MethodCandidate candidate, OverloadInfo newOverload, OverloadInfo oldOverload)
        {
            List <ParameterWrapper> newWrappers = new List <ParameterWrapper>();

            for (int i = 0; i < candidate.ParameterCount; i++)
            {
                ParameterWrapper oldWrap = candidate.GetParameter(i);
                ParameterInfo    pi      = null;
                Type             newType = oldWrap.Type;
                if (oldWrap.ParameterInfo != null)
                {
                    pi = newOverload.Parameters[oldWrap.ParameterInfo.Position];
                    ParameterInfo oldParam = oldOverload.Parameters[oldWrap.ParameterInfo.Position];

                    if (oldParam.ParameterType == oldWrap.Type)
                    {
                        newType = pi.ParameterType;
                    }
                    else if (pi.ParameterType.IsByRef)
                    {
                        newType = pi.ParameterType.GetElementType();
                        if (oldParam.ParameterType.GetElementType() != oldWrap.Type)
                        {
                            Debug.Assert(CompilerHelpers.IsStrongBox(oldWrap.Type));
                            newType = typeof(StrongBox <>).MakeGenericType(newType);
                        }
                    }
                    else
                    {
                        Debug.Assert(oldParam.ParameterType.GetElementType() == oldWrap.Type);
                        newType = pi.ParameterType.GetElementType();
                    }
                }

                newWrappers.Add(new ParameterWrapper(pi, newType, oldWrap.Name, oldWrap.Flags));
            }
            return(newWrappers);
        }
예제 #17
0
        private void AddBasicMethodTargets(OverloadInfo method) {
            Assert.NotNull(method);

            var mapping = new ParameterMapping(this, method, _argNames);

            mapping.MapParameters(false);

            foreach (var defaultCandidate in mapping.CreateDefaultCandidates()) {
                AddSimpleTarget(defaultCandidate);
            }

            var byRefReducedCandidate = mapping.CreateByRefReducedCandidate();
            if (byRefReducedCandidate != null) {
                AddSimpleTarget(byRefReducedCandidate);
            }

            AddSimpleTarget(mapping.CreateCandidate());
        }
예제 #18
0
 internal RubyMethodGroupInfo(OverloadInfo/*!*/[]/*!*/ methods, RubyModule/*!*/ declaringModule, bool isStatic)
     : base(methods, RubyMemberFlags.Public, declaringModule) {
     _isStatic = isStatic;
 }
예제 #19
0
파일: RubyClass.cs 프로젝트: kashano/main
        private RubyOverloadGroupInfo/*!*/ MakeGroup(ICollection<ClrOverloadInfo>/*!*/ allMethods) {
            var overloads = new OverloadInfo[allMethods.Count];
            var overloadOwners = new RubyOverloadGroupInfo[overloads.Length];
            int i = 0;
            foreach (var entry in allMethods) {
                overloads[i] = entry.Overload;
                overloadOwners[i] = entry.Owner;
                i++;
            }

            var result = new RubyOverloadGroupInfo(overloads, this, overloadOwners, _isSingletonClass);
            
            // update ownership of overloads owned by the new group:
            foreach (var entry in allMethods) {
                if (entry.Owner != null) {
                    entry.Owner.CachedInGroup(result);
                } else {
                    entry.Owner = result;
                }
            }

            return result;
        }
예제 #20
0
        /// <summary>
        /// Builds a mapping based upon generic parameter constraints between related generic
        /// parameters.  This is then used to sort the generic parameters so that we can process
        /// the least dependent parameters first.  For example given the method:
        /// 
        /// void Foo{T0, T1}(T0 x, T1 y) where T0 : T1 
        /// 
        /// We need to first infer the type information for T1 before we infer the type information
        /// for T0 so that we can ensure the constraints are correct.
        /// </summary>
        private static Dictionary<Type, List<Type>> GetDependencyMapping(OverloadInfo info) {
            Dictionary<Type, List<Type>> dependencies = new Dictionary<Type, List<Type>>();

            // need to calculate any dependencies between parameters.
            foreach (Type genArg in info.GenericArguments) {
                Type[] constraints = genArg.GetGenericParameterConstraints();
                foreach (Type t in constraints) {
                    if (t.IsGenericParameter) {
                        AddDependency(dependencies, genArg, t);
                    } else if (t.ContainsGenericParameters) {
                        AddNestedDependencies(dependencies, genArg, t);
                    }
                }
            }
            return dependencies;
        }
예제 #21
0
        /// <summary>
        /// Gets the generic type arguments sorted so that the type arguments
        /// that are depended upon by other type arguments are sorted before
        /// their dependencies.
        /// </summary>
        private static Type[] GetSortedGenericArguments(OverloadInfo info, Dictionary<Type, List<Type>> dependencies) {
            Type[] genArgs = ArrayUtils.MakeArray(info.GenericArguments);

            // Then sort the arguments based upon those dependencies
            Array.Sort(genArgs, (x, y) => {
                if (Object.ReferenceEquals(x, y)) {
                    return 0;
                }

                bool isDependent = IsDependentConstraint(dependencies, x, y);
                if (isDependent) {
                    return 1;
                }

                isDependent = IsDependentConstraint(dependencies, y, x);
                if (isDependent) {
                    return -1;
                }

                int xhash = x.GetHashCode(), yhash = y.GetHashCode();
                if (xhash != yhash) {
                    return xhash - yhash;
                }

                long idDiff = IdDispenser.GetId(x) - IdDispenser.GetId(y);
                return idDiff > 0 ? 1 : -1;
            });


            return genArgs;
        }
예제 #22
0
        /// <summary>
        /// Creates a new list of ParameterWrappers for the generic method replacing the old parameters with the new ones.
        /// </summary>
        private static List<ParameterWrapper> CreateNewWrappers(MethodCandidate candidate, OverloadInfo newOverload, OverloadInfo oldOverload) {
            List<ParameterWrapper> newWrappers = new List<ParameterWrapper>();
            for (int i = 0; i < candidate.ParameterCount; i++) {
                ParameterWrapper oldWrap = candidate.GetParameter(i);
                ParameterInfo pi = null;
                Type newType = oldWrap.Type;
                if (oldWrap.ParameterInfo != null) {
                    pi = newOverload.Parameters[oldWrap.ParameterInfo.Position];
                    ParameterInfo oldParam = oldOverload.Parameters[oldWrap.ParameterInfo.Position];

                    if (oldParam.ParameterType == oldWrap.Type) {
                        newType = pi.ParameterType;
                    } else if (pi.ParameterType.IsByRef) {
                        newType = pi.ParameterType.GetElementType();
                        if (oldParam.ParameterType.GetElementType() != oldWrap.Type) {
                            Debug.Assert(CompilerHelpers.IsStrongBox(oldWrap.Type));
                            newType = typeof(StrongBox<>).MakeGenericType(newType);
                        }
                    } else {
                        Debug.Assert(oldParam.ParameterType.GetElementType() == oldWrap.Type);
                        newType = pi.ParameterType.GetElementType();
                    }
                }

                newWrappers.Add(new ParameterWrapper(pi, newType, oldWrap.Name, oldWrap.Flags));
            }
            return newWrappers;
        }
예제 #23
0
        /// <summary>
        /// Creates a new set of arg builders for the given generic method definition which target the new
        /// parameters.
        /// </summary>
        private static List<ArgBuilder> CreateNewArgBuilders(MethodCandidate candidate, OverloadInfo newOverload) {
            List<ArgBuilder> argBuilders = new List<ArgBuilder>();
            foreach (ArgBuilder oldArgBuilder in candidate.ArgBuilders) {
                var pi = oldArgBuilder.ParameterInfo;

                if (pi != null && (pi.ParameterType.IsGenericParameter || pi.ParameterType.ContainsGenericParameters)) {
                    ArgBuilder replacement = oldArgBuilder.Clone(newOverload.Parameters[pi.Position]);

                    if (replacement == null) {
                        return null;
                    }
                    argBuilders.Add(replacement);
                } else {
                    argBuilders.Add(oldArgBuilder);
                }
            }
            return argBuilders;
        }
예제 #24
0
 /// <summary>
 /// Gets the generic arguments for method based upon the constraints discovered during
 /// type inference.  Returns null if not all generic arguments had their types inferred.
 /// </summary>
 private static Type[] GetGenericArgumentsForInferedMethod(OverloadInfo target, Dictionary<Type, Type> constraints) {
     Type[] genArgs = ArrayUtils.MakeArray(target.GenericArguments);
     for (int i = 0; i < genArgs.Length; i++) {
         Type newType;
         if (!constraints.TryGetValue(genArgs[i], out newType)) {
             // we didn't discover any types for this type argument
             return null;
         }
         genArgs[i] = newType;
     }
     return genArgs;
 }
예제 #25
0
        internal static void GetParameterCount(OverloadInfo/*!*/ method, SelfCallConvention callConvention, out int mandatory, out int optional) {
            mandatory = 0;
            optional = 0;
            for (int i = GetHiddenParameterCount(method, callConvention); i < method.ParameterCount; i++) {
                var info = method.Parameters[i];

                if (method.IsParamArray(i)) {
                    // TODO: indicate splat args separately?
                    optional++;
                } else if (info.IsOutParameter()) {
                    // Python allows passing of optional "clr.Reference" to capture out parameters
                    // Ruby should allow similar
                    optional++;
                } else if (info.IsMandatory()) {
                    mandatory++;
                } else {
                    optional++;
                }
            }
        }
예제 #26
0
 protected override bool AllowMemberInitialization(OverloadInfo method) {
     return false;
 }
예제 #27
0
파일: RubyClass.cs 프로젝트: kashano/main
        public void BuildObjectConstructionNoFlow(MetaObjectBuilder/*!*/ metaBuilder, CallArguments/*!*/ args, string/*!*/ methodName) {
            if (IsSingletonClass) {
                metaBuilder.SetError(Methods.MakeVirtualClassInstantiatedError.OpCall());
                return;
            }

            Type type = GetUnderlyingSystemType();

            RubyMemberInfo initializer;
            using (Context.ClassHierarchyLocker()) {
                // check version of the class so that we invalidate the rule whenever the initializer changes:
                metaBuilder.AddVersionTest(this);

                initializer = ResolveMethodForSiteNoLock(Symbols.Initialize, VisibilityContext.AllVisible).Info;

                // Initializer resolves to BasicObject#initialize unless overridden in a derived class.
                // We ensure that initializer cannot be removed/undefined so that we don't ever fall back to method_missing (see RubyModule.RemoveMethodNoEvent).
                Debug.Assert(initializer != null);
            }

            bool isLibraryMethod = initializer is RubyLibraryMethodInfo;
            bool isRubyInitializer = initializer.IsRubyMember && !isLibraryMethod;
            bool isLibraryInitializer = isLibraryMethod && !initializer.DeclaringModule.IsObjectClass && !initializer.DeclaringModule.IsBasicObjectClass;

            if (isRubyInitializer || isLibraryInitializer && _isRubyClass) {
                // allocate and initialize:
                bool allocatorFound = BuildAllocatorCall(metaBuilder, args, () => AstUtils.Constant(Name));
                if (metaBuilder.Error) {
                    return;
                }

                if (!allocatorFound) {
                    metaBuilder.SetError(Methods.MakeMissingDefaultConstructorError.OpCall(
                        Ast.Convert(args.TargetExpression, typeof(RubyClass)),
                        Ast.Constant(initializer.DeclaringModule.Name)
                    ));
                    return;
                }

                if (!initializer.IsEmpty) {
                    BuildOverriddenInitializerCall(metaBuilder, args, initializer);
                }
            } else {
                // construct:
                OverloadInfo[] constructionOverloads;
                SelfCallConvention callConvention = SelfCallConvention.SelfIsParameter;
                bool implicitProtocolConversions = false;

                if (typeof(Delegate).IsAssignableFrom(type)) {
                    BuildDelegateConstructorCall(metaBuilder, args, type);
                    return;
                } else if (type.IsArray && type.GetArrayRank() == 1) {
                    constructionOverloads = GetClrVectorFactories();
                } else if (_structInfo != null) {
                    constructionOverloads = new OverloadInfo[] { new ReflectionOverloadInfo(Methods.CreateStructInstance) };
                } else if (_factories.Length != 0) {
                    constructionOverloads = ArrayUtils.ConvertAll(_factories, (d) => new ReflectionOverloadInfo(d.GetMethod()));
                } else {
                    // TODO: handle protected constructors
                    constructionOverloads = GetConstructors(type == typeof(object) ? typeof(RubyObject) : type).ToArray();

                    if (type.IsValueType()) {
                        if (constructionOverloads.Length == 0 || GetConstructor(type) == null) {
                            constructionOverloads = ArrayUtils.Append(constructionOverloads, new ReflectionOverloadInfo(Methods.CreateDefaultInstance));
                        }
                    } else if (constructionOverloads.Length == 0) {
                        metaBuilder.SetError(Methods.MakeAllocatorUndefinedError.OpCall(Ast.Convert(args.TargetExpression, typeof(RubyClass))));
                        return;
                    }

                    callConvention = SelfCallConvention.NoSelf;
                    implicitProtocolConversions = true;
                }

                RubyMethodGroupInfo.BuildCallNoFlow(metaBuilder, args, methodName, constructionOverloads, callConvention, implicitProtocolConversions);

                if (!metaBuilder.Error) {
                    metaBuilder.Result = MarkNewException(metaBuilder.Result);

                    // we need to handle break, which unwinds to a proc-converter that could be this method's frame:
                    if (args.Signature.HasBlock) {
                        metaBuilder.ControlFlowBuilder = RubyMethodGroupInfo.RuleControlFlowBuilder;
                    }
                }
            }
        }
예제 #28
0
 internal MethodCandidate ReplaceMethod(OverloadInfo newMethod, List <ParameterWrapper> parameters, IList <ArgBuilder> argBuilders, Dictionary <DynamicMetaObject, BindingRestrictions> restrictions)
 {
     return(new MethodCandidate(Resolver, newMethod, parameters, _paramsDict, ReturnBuilder, _instanceBuilder, argBuilders, restrictions));
 }
예제 #29
0
        /// <summary>
        /// Checks to see if the language allows named arguments to be bound to instance fields or
        /// properties and turned into setters. By default this is only allowed on contructors.
        /// </summary>
        internal protected virtual bool AllowMemberInitialization(OverloadInfo method) {
#pragma warning disable 618 // obsolete
            return AllowKeywordArgumentSetting(method.ReflectionInfo);
#pragma warning restore 618
        }
예제 #30
0
        /// <summary>
        /// Creates a new set of arg builders for the given generic method definition which target the new
        /// parameters.
        /// </summary>
        private static List <ArgBuilder> CreateNewArgBuilders(MethodCandidate candidate, OverloadInfo newOverload)
        {
            List <ArgBuilder> argBuilders = new List <ArgBuilder>();

            foreach (ArgBuilder oldArgBuilder in candidate.ArgBuilders)
            {
                var pi = oldArgBuilder.ParameterInfo;

                if (pi != null && (pi.ParameterType.IsGenericParameter || pi.ParameterType.ContainsGenericParameters()))
                {
                    ArgBuilder replacement = oldArgBuilder.Clone(newOverload.Parameters[pi.Position]);

                    if (replacement == null)
                    {
                        return(null);
                    }
                    argBuilders.Add(replacement);
                }
                else
                {
                    argBuilders.Add(oldArgBuilder);
                }
            }
            return(argBuilders);
        }
예제 #31
0
 protected abstract RubyMemberInfo/*!*/ Copy(OverloadInfo/*!*/[]/*!*/ methods);
예제 #32
0
 protected override RubyMemberInfo/*!*/ Copy(OverloadInfo/*!*/[]/*!*/ methods) {
     return new RubyMethodGroupInfo(this, methods);
 }
예제 #33
0
 // copy ctor
 private RubyMethodGroupInfo(RubyMethodGroupInfo/*!*/ info, OverloadInfo/*!*/[] methods)
     : base(methods, info.Flags, info.DeclaringModule) {
     _isStatic = info._isStatic;
 }
예제 #34
0
 protected override bool AllowMemberInitialization(OverloadInfo method)
 {
     return method.IsInstanceFactory && !method.DeclaringType.GetTypeInfo().IsDefined(typeof(PythonTypeAttribute), true);
 }
예제 #35
0
 private static bool IsUnsupported(OverloadInfo method) {
     return (method.CallingConvention & CallingConventions.VarArgs) != 0;
 }
예제 #36
0
파일: RubyClass.cs 프로젝트: kashano/main
        private RubyMethodGroupInfo/*!*/ MakeGroup(IEnumerable<OverloadInfo/*!*/>/*!*/ members, int visibleMemberCount, bool specialNameOnly, bool isDetached) {
            var allMethods = new OverloadInfo[visibleMemberCount];
            int i = 0;
            foreach (var method in members) {
                if (IsVisible(method.Attributes, method.DeclaringType, specialNameOnly)) {
                    allMethods[i++] = method;
                }
            }

            return isDetached ? 
                new RubyMethodGroupInfo(allMethods, this, _isSingletonClass) :
                new RubyOverloadGroupInfo(allMethods, this, null, _isSingletonClass);
        }
예제 #37
0
        private bool IsOverloadSignature(OverloadInfo/*!*/ method, Type/*!*/[]/*!*/ parameterTypes) {
            int firstInfo = RubyOverloadResolver.GetHiddenParameterCount(method, CallConvention);
            var infos = method.Parameters;
            
            if (infos.Count - firstInfo != parameterTypes.Length) {
                return false;
            }

            for (int i = 0; i < parameterTypes.Length; i++) {
                if (infos[firstInfo + i].ParameterType != parameterTypes[i]) {
                    return false;
                }
            }

            return true;
        }
예제 #38
0
 private static bool HasBlockParameter(OverloadInfo/*!*/ method) {
     foreach (ParameterInfo param in method.Parameters) {
         if (param.ParameterType == typeof(BlockParam)) {
             return true;
         }
     }
     return false;
 }
예제 #39
0
 // copy ctor
 private RubyLibraryMethodInfo(RubyLibraryMethodInfo/*!*/ info, OverloadInfo/*!*/[]/*!*/ methods)
     : base(methods, info.Flags, info.DeclaringModule) {
 }