internal ConstructorFunction(BuiltinFunction realTarget, IList<MethodBase> constructors) : base("__new__", ArrayUtils.ToArray(GetTargetsValidateFunction(realTarget)), realTarget.DeclaringType, FunctionType.Function | FunctionType.AlwaysVisible) { base.Name = realTarget.Name; base.FunctionType = realTarget.FunctionType; this._ctors = ArrayUtils.ToArray(constructors); }
private object GetOverload(Type[] sig, IList<MethodBase> targets, bool wrapCtors) { // We can still end up with more than one target since generic and non-generic // methods can share the same name and signature. So we'll build up a new // reflected method with all the candidate targets. A caller can then index this // reflected method if necessary in order to provide generic type arguments and // fully disambiguate the target. // Search for targets with the right number of arguments. BuiltinFunction bf; BuiltinFunction.TypeList tl = new BuiltinFunction.TypeList(sig); lock (_function.OverloadDictionary) { if (!_function.OverloadDictionary.TryGetValue(tl, out bf)) { MethodBase[] newTargets = FindMatchingTargets(sig, targets); if (targets == null) throw ScriptingRuntimeHelpers.SimpleTypeError(String.Format("No match found for the method signature {0}", sig)); // TODO: Sig to usable display _function.OverloadDictionary[tl] = bf = new BuiltinFunction(_function.Name, newTargets, Function.DeclaringType, _function.FunctionType); } } if (_instance != null) { return bf.BindToInstance(_instance); } else if (wrapCtors) { return GetTargetFunction(bf); } else { return bf; } }
private object CallGetter(CodeContext context, PythonType owner, SiteLocalStorage <CallSite <Func <CallSite, CodeContext, object, object> > > storage, object instance) { if (NeedToReturnProperty(instance, Getter)) { return(this); } if (Getter.Length == 0) { throw new MissingMemberException("unreadable property"); } if (owner == null) { owner = DynamicHelpers.GetPythonType(instance); } // this matches the logic in the default binder when it does a property get. We // need to duplicate it here to be consistent for all gets. MethodInfo[] members = Getter; Type type = owner.UnderlyingSystemType; if (Getter.Length > 1) { // if we were given multiple members pick the member closest to the type... Type bestMemberDeclaringType = Getter[0].DeclaringType; MethodInfo bestMember = Getter[0]; for (int i = 1; i < Getter.Length; i++) { MethodInfo mt = Getter[i]; if (!IsApplicableForType(type, mt)) { continue; } if (Getter[i].DeclaringType.IsSubclassOf(bestMemberDeclaringType) || !IsApplicableForType(type, bestMember)) { bestMember = Getter[i]; bestMemberDeclaringType = Getter[i].DeclaringType; } } members = new MethodInfo[] { bestMember }; } BuiltinFunction target = PythonTypeOps.GetBuiltinFunction(type, __name__, members); // Workaround for https://github.com/IronLanguages/ironpython3/issues/1326 Debug.Assert(members.Length == 1); if (members[0].IsStatic) { instance = null; } return(target.Call0(context, storage, instance)); }
public BuiltinFunctionInfo(BuiltinFunction function, ProjectState projectState) : base(ClrModule.GetPythonType(typeof(BuiltinFunction)), projectState) { // TODO: get return information, parameters, members _function = function; _returnTypes = Utils.GetReturnTypes(function, projectState); _doc = null; }
internal static void CheckSelfWorker(CodeContext/*!*/ context, object self, BuiltinFunction template) { // to a fast check on the CLR types, if they match we can avoid the slower // check that involves looking up dynamic types. (self can be null on // calls like set.add(None) Type selfType = CompilerHelpers.GetType(self); if (selfType != template.DeclaringType && !template.DeclaringType.IsAssignableFrom(selfType)) { // if a conversion exists to the type allow the call. context.LanguageContext.Binder.Convert(self, template.DeclaringType); } }
internal static BuiltinFunction/*!*/ MakeOrAdd(BuiltinFunction existing, string name, MethodBase mi, Type declaringType, FunctionType funcType) { PythonBinder.AssertNotExtensionType(declaringType); if (existing != null) { existing._data.AddMethod(mi); return existing; } else { return MakeMethod(name, mi, declaringType, funcType); } }
internal BuiltinFunctionOverloadResult(ProjectState state, BuiltinFunction overload, int removedParams, string name, params ParameterResult[] extraParams) : base(null, name) { _overload = overload; _extraParameters = extraParams; _removedParams = removedParams; _projectState = state; CalculateDocumentation(); }
protected override object GetTargetFunction(BuiltinFunction bf) { // return a function that's bound to the overloads, we'll // the user then calls this w/ the dynamic type, and the bound // function drops the class & calls the overload. if (bf.Targets[0].DeclaringType != typeof(InstanceOps)) { return(new ConstructorFunction(InstanceOps.OverloadedNew, bf.Targets).BindToInstance(bf)); } return(base.GetTargetFunction(bf)); }
/// <summary> /// Returns a BuiltinFunction bound to the provided type arguments. Returns null if the binding /// cannot be performed. /// </summary> internal BuiltinFunction MakeGenericMethod(Type[] types) { TypeList tl = new TypeList(types); // check for cached method first... BuiltinFunction bf; if (_data.BoundGenerics != null) { lock (_data.BoundGenerics) { if (_data.BoundGenerics.TryGetValue(tl, out bf)) { return(bf); } } } // Search for generic targets with the correct arity (number of type parameters). // Compatible targets must be MethodInfos by definition (constructors never take // type arguments). List <MethodBase> targets = new List <MethodBase>(Targets.Count); foreach (MethodBase mb in Targets) { MethodInfo mi = mb as MethodInfo; if (mi == null) { continue; } if (mi.ContainsGenericParameters && mi.GetGenericArguments().Length == types.Length) { targets.Add(mi.MakeGenericMethod(types)); } } if (targets.Count == 0) { return(null); } // Build a new ReflectedMethod that will contain targets with bound type arguments & cache it. bf = new BuiltinFunction(Name, targets.ToArray(), DeclaringType, FunctionType); EnsureBoundGenericDict(); lock (_data.BoundGenerics) { _data.BoundGenerics[tl] = bf; } return(bf); }
/// <summary> /// Trys to get the BuiltinFunction for the given name on the type of the provided MetaObject. /// /// Succeeds if the MetaObject is a BuiltinFunction or BuiltinMethodDescriptor. /// </summary> internal static bool TryGetStaticFunction(BinderState/*!*/ state, SymbolId op, DynamicMetaObject/*!*/ mo, out BuiltinFunction function) { PythonType type = MetaPythonObject.GetPythonType(mo); function = null; if (op != SymbolId.Empty) { PythonTypeSlot xSlot; object val; if (type.TryResolveSlot(state.Context, op, out xSlot) && xSlot.TryGetValue(state.Context, null, type, out val)) { function = TryConvertToBuiltinFunction(val); if (function == null) return false; } } return true; }
private bool Equals(BuiltinFunction other) { if (this == other) { return(true); } if (!IsUnbound && !other.IsUnbound) { return(_instance == other._instance && _data == other._data); } return(false); }
/// <summary> /// Tries to get the BuiltinFunction for the given name on the type of the provided MetaObject. /// /// Succeeds if the MetaObject is a BuiltinFunction or BuiltinMethodDescriptor. /// </summary> internal static bool TryGetStaticFunction(PythonContext/*!*/ state, string op, DynamicMetaObject/*!*/ mo, out BuiltinFunction function) { PythonType type = MetaPythonObject.GetPythonType(mo); function = null; if (!String.IsNullOrEmpty(op)) { PythonTypeSlot xSlot; object val; if (type.TryResolveSlot(state.SharedContext, op, out xSlot) && xSlot.TryGetValue(state.SharedContext, null, type, out val)) { function = TryConvertToBuiltinFunction(val); if (function == null) return false; } } return true; }
private object GetOverload(Type[] sig, IList <MethodBase> targets, bool wrapCtors) { // We can still end up with more than one target since generic and non-generic // methods can share the same name and signature. So we'll build up a new // reflected method with all the candidate targets. A caller can then index this // reflected method if necessary in order to provide generic type arguments and // fully disambiguate the target. BuiltinFunction bf; BuiltinFunction.TypeList tl = new BuiltinFunction.TypeList(sig); lock (_function.OverloadDictionary) { if (!_function.OverloadDictionary.TryGetValue(tl, out bf)) { MethodBase[] newTargets = FindMatchingTargets(sig, targets, true); if (newTargets.Length == 0) { // If no overload was found, check also using CodeContext for backward compatibility newTargets = FindMatchingTargets(sig, targets, false); } if (newTargets.Length == 0) { ThrowOverloadException(sig, targets); } else { _function.OverloadDictionary[tl] = bf = new BuiltinFunction(_function.Name, newTargets, Function.DeclaringType, _function.FunctionType); } } } if (_instance != null) { return(bf.BindToInstance(_instance)); } else if (wrapCtors) { return(GetTargetFunction(bf)); } else { return(bf); } }
/// <summary> /// Use indexing on generic methods to provide a new reflected method with targets bound with /// the supplied type arguments. /// </summary> public BuiltinFunction /*!*/ this[params object[] key] { get { // Retrieve the list of type arguments from the index. Type[] types = new Type[key.Length]; for (int i = 0; i < types.Length; i++) { types[i] = Converter.ConvertToType(key[i]); } BuiltinFunction res = MakeGenericMethod(types); if (res == null) { bool hasGenerics = false; foreach (MethodBase mb in Targets) { MethodInfo mi = mb as MethodInfo; if (mi != null && mi.ContainsGenericParameters) { hasGenerics = true; } } if (hasGenerics) { throw PythonOps.TypeError(string.Format("bad type args to this generic method {0}", Name)); } else { throw PythonOps.TypeError(string.Format("{0} is not a generic method and is unsubscriptable", Name)); } } if (IsUnbound) { return(res); } return(new BuiltinFunction(_instance, res._data)); } }
private object GetOverload(Type[] sig, IList <MethodBase> targets, bool wrapCtors) { // We can still end up with more than one target since generic and non-generic // methods can share the same name and signature. So we'll build up a new // reflected method with all the candidate targets. A caller can then index this // reflected method if necessary in order to provide generic type arguments and // fully disambiguate the target. // Search for targets with the right number of arguments. BuiltinFunction bf; BuiltinFunction.TypeList tl = new BuiltinFunction.TypeList(sig); lock (_function.OverloadDictionary) { if (!_function.OverloadDictionary.TryGetValue(tl, out bf)) { MethodBase[] newTargets = FindMatchingTargets(sig, targets); if (targets == null) { throw ScriptingRuntimeHelpers.SimpleTypeError(String.Format("No match found for the method signature {0}", sig)); // TODO: Sig to usable display } _function.OverloadDictionary[tl] = bf = new BuiltinFunction(_function.Name, newTargets, Function.DeclaringType, _function.FunctionType); } } if (_instance != null) { return(bf.BindToInstance(_instance)); } else if (wrapCtors) { return(GetTargetFunction(bf)); } else { return(bf); } }
public int __cmp__(CodeContext /*!*/ context, [NotNull] BuiltinFunction /*!*/ other) { if (other == this) { return(0); } if (!IsUnbound && !other.IsUnbound) { int result = PythonOps.Compare(__self__, other.__self__); if (result != 0) { return(result); } if (_data == other._data) { return(0); } } int res = String.CompareOrdinal(__name__, other.__name__); if (res != 0) { return(res); } res = String.CompareOrdinal(Get__module__(context), other.Get__module__(context)); if (res != 0) { return(res); } long lres = IdDispenser.GetId(this) - IdDispenser.GetId(other); return(lres > 0 ? 1 : -1); }
public BuiltinNewAdapter(ArgumentValues/*!*/ ai, PythonType/*!*/ creating, BuiltinFunction/*!*/ ctor, PythonContext/*!*/ state, Expression/*!*/ codeContext) : base(ai, state, codeContext) { _creating = creating; _ctor = ctor; }
public bool __ne__([NotNone] BuiltinFunction /*!*/ other) => !Equals(other);
internal void SetConstructor(BuiltinFunction ctor) { _ctor = ctor; }
public SpecializedBuiltinFunction(ProjectState state, BuiltinFunction function, Func<CallExpression, AnalysisUnit, ISet<Namespace>[], ISet<Namespace>> call) : base(function, state) { _call = call; }
/// <summary> /// Creates a new CallableObject. If BuiltinFunction is available we'll create a BuiltinCallable otherwise /// we create a SlotCallable. /// </summary> public static Callable MakeCallable(PythonContext/*!*/ binder, PythonIndexType op, BuiltinFunction itemFunc, PythonTypeSlot itemSlot) { if (itemFunc != null) { // we'll call a builtin function to produce the rule return new BuiltinCallable(binder, op, itemFunc); } else if (itemSlot != null) { // we'll call a PythonTypeSlot to produce the rule return new SlotCallable(binder, op, itemSlot); } return null; }
private static BuiltinFunction CheckAlwaysNotImplemented(BuiltinFunction xBf) { if (xBf != null) { bool returnsValue = false; foreach (MethodBase mb in xBf.Targets) { if (mb.GetReturnType() != typeof(NotImplementedType) || mb.IsDefined(typeof(Python3WarningAttribute), true)) { returnsValue = true; break; } } if (!returnsValue) { xBf = null; } } return xBf; }
private static ICollection<OverloadDoc> GetBuiltinFunctionOverloads(BuiltinFunction bf) { OverloadDoc[] res = new OverloadDoc[bf.Targets.Count]; for (int i = 0; i < bf.Targets.Count; i++) { res[i] = GetOverloadDoc(bf.__name__, bf.Targets[i]); } return res; }
private void MakeGetFunc() { _getfunc = PythonTypeOps.GetBuiltinFunction(DeclaringType, __name__, _getter); }
private static IList<MethodBase> GetTargetsValidateFunction(BuiltinFunction realTarget) { ContractUtils.RequiresNotNull(realTarget, "realTarget"); return realTarget.Targets; }
public bool __eq__([NotNull] BuiltinFunction /*!*/ other) => Equals(other);
private PythonTuple _allOverloads; // overloads are stored here and may be bound to an instance public BuiltinFunctionOverloadMapper(BuiltinFunction builtinFunction, object instance) { this._function = builtinFunction; this._instance = instance; }
protected override object GetTargetFunction(BuiltinFunction bf) { // return a function that's bound to the overloads, we'll // the user then calls this w/ the dynamic type, and the bound // function drops the class & calls the overload. if (bf.Targets[0].DeclaringType != typeof(InstanceOps)) { return new ConstructorFunction(InstanceOps.OverloadedNew, bf.Targets).BindToInstance(bf); } return base.GetTargetFunction(bf); }
protected virtual object GetTargetFunction(BuiltinFunction bf) { return bf; }
public BuiltinInitAdapter(ArgumentValues/*!*/ ai, BuiltinFunction/*!*/ method, PythonContext/*!*/ state, Expression/*!*/ codeContext) : base(ai, state, codeContext) { _method = method; }
internal ClassMethodDescriptor(BuiltinFunction func) { this._func = func; }
private static IList <MethodBase> GetTargetsValidateFunction(BuiltinFunction realTarget) { ContractUtils.RequiresNotNull(realTarget, "realTarget"); return(realTarget.Targets); }
internal object CallTarget(CodeContext context, SiteLocalStorage <CallSite <Func <CallSite, CodeContext, object, object[], object> > > storage, MethodInfo[] targets, object instance, params object[] args) { BuiltinFunction target = PythonTypeOps.GetBuiltinFunction(DeclaringType, __name__, targets); return(target.Call(context, storage, instance, args)); }
private static BuiltinFunction CheckAlwaysNotImplemented(BuiltinFunction xBf) { if (xBf != null) { bool returnsValue = false; foreach (MethodBase mb in xBf.Targets) { if (CompilerHelpers.GetReturnType(mb) != typeof(NotImplementedType)) { returnsValue = true; break; } } if (!returnsValue) { xBf = null; } } return xBf; }
internal BuiltinMethodDescriptor(BuiltinFunction/*!*/ function) { _template = function; }
internal static ConstructorFunction GetConstructor(Type type, BuiltinFunction realTarget, params MethodBase[] mems) { ConstructorFunction res = null; if (mems.Length != 0) { ReflectionCache.MethodBaseCache cache = new ReflectionCache.MethodBaseCache("__new__", mems); lock (_ctors) { if (!_ctors.TryGetValue(cache, out res)) { _ctors[cache] = res = new ConstructorFunction(realTarget, mems); } } } return res; }
public MetaBuiltinFunction(Expression/*!*/ expression, BindingRestrictions/*!*/ restrictions, BuiltinFunction/*!*/ value) : base(expression, BindingRestrictions.Empty, value) { Assert.NotNull(value); }
protected virtual object GetTargetFunction(BuiltinFunction bf) { return(bf); }
public BuiltinCallable(PythonContext/*!*/ binder, PythonIndexType op, BuiltinFunction/*!*/ func) : base(binder, op) { Assert.NotNull(func); _bf = func; }
public BuiltinCallable(BinderState/*!*/ binder, string op, BuiltinFunction/*!*/ func) : base(binder, op) { Assert.NotNull(func); _bf = func; }
internal static PythonTypeSlot/*!*/ GetFinalSlotForFunction(BuiltinFunction/*!*/ func) { if ((func.FunctionType & FunctionType.Method) != 0) { BuiltinMethodDescriptor desc; lock (_methodCache) { if (!_methodCache.TryGetValue(func, out desc)) { _methodCache[func] = desc = new BuiltinMethodDescriptor(func); } return desc; } } if (func.Targets[0].IsDefined(typeof(ClassMethodAttribute), true)) { lock (_classMethodCache) { ClassMethodDescriptor desc; if (!_classMethodCache.TryGetValue(func, out desc)) { _classMethodCache[func] = desc = new ClassMethodDescriptor(func); } return desc; } } return func; }
private void InitializeUserType(CodeContext/*!*/ context, string name, PythonTuple bases, IAttributesCollection vars) { // we don't support overriding __mro__ if (vars.ContainsKey(Symbols.MethodResolutionOrder)) throw new NotImplementedException("Overriding __mro__ of built-in types is not implemented"); // cannot override mro when inheriting from type if (vars.ContainsKey(SymbolTable.StringToId("mro"))) { foreach (object o in bases) { PythonType dt = o as PythonType; if (dt != null && dt.IsSubclassOf(TypeCache.PythonType)) { throw new NotImplementedException("Overriding type.mro is not implemented"); } } } bases = ValidateBases(bases); _name = name; _bases = GetBasesAsList(bases).ToArray(); _pythonContext = PythonContext.GetContext(context); _resolutionOrder = CalculateMro(this, _bases); foreach (PythonType pt in _bases) { pt.AddSubType(this); _originalSlotCount += pt.SlotCount; } BuildUserTypeDictionary(context, vars); InitializeSlots(name, bases, vars); // calculate the .NET type once so it can be used for things like super calls _underlyingSystemType = NewTypeMaker.GetNewType(name, bases, vars); // then let the user intercept and rewrite the type - the user can't create // instances of this type yet. _underlyingSystemType = __clrtype__(); // finally assign the ctors from the real type the user provided _ctor = BuiltinFunction.MakeMethod(Name, _underlyingSystemType.GetConstructors(), _underlyingSystemType, FunctionType.Function); }
internal BuiltinMethodDescriptor(BuiltinFunction /*!*/ function) { _template = function; }
/// <summary> /// Returns a BuiltinFunction bound to the provided type arguments. Returns null if the binding /// cannot be performed. /// </summary> internal BuiltinFunction MakeGenericMethod(Type[] types) { TypeList tl = new TypeList(types); // check for cached method first... BuiltinFunction bf; if (_data.BoundGenerics != null) { lock (_data.BoundGenerics) { if (_data.BoundGenerics.TryGetValue(tl, out bf)) { return bf; } } } // Search for generic targets with the correct arity (number of type parameters). // Compatible targets must be MethodInfos by definition (constructors never take // type arguments). List<MethodBase> targets = new List<MethodBase>(Targets.Count); foreach (MethodBase mb in Targets) { MethodInfo mi = mb as MethodInfo; if (mi == null) continue; if (mi.ContainsGenericParameters && mi.GetGenericArguments().Length == types.Length) targets.Add(mi.MakeGenericMethod(types)); } if (targets.Count == 0) { return null; } // Build a new ReflectedMethod that will contain targets with bound type arguments & cache it. bf = new BuiltinFunction(Name, targets.ToArray(), DeclaringType, FunctionType); EnsureBoundGenericDict(); lock (_data.BoundGenerics) { _data.BoundGenerics[tl] = bf; } return bf; }