コード例 #1
0
 public static IReadOnlyList <IPythonType> GetTypeArgumentsFromParameters(IPythonFunctionOverload o, IArgumentSet args)
 {
     if (o.Parameters.Any(p => p.IsGeneric))
     {
         // Declaring class is not generic, but the function is and arguments
         // should provide actual specific types.
         // TODO: handle keyword and dict args
         var list = new List <IPythonType>();
         for (var i = 0; i < Math.Min(o.Parameters.Count, args.Arguments.Count); i++)
         {
             if (o.Parameters[i].IsGeneric)
             {
                 list.AddRange(GetSpecificTypeFromArgumentValue(args.Arguments[i].Value));
             }
         }
         return(list);
     }
     return(null);
 }
コード例 #2
0
        public IMember Call(IArgumentSet args, IPythonType self, Node callLocation = null)
        {
            if (!_fromAnnotation)
            {
                // First try supplied specialization callback.
                var rt = _returnValueProvider?.Invoke(DeclaringModule, this, args);
                if (!rt.IsUnknown())
                {
                    return(rt);
                }
            }

            // If function returns generic, determine actual type based on the passed in specific type (self).
            // If there is no self and no declaring type, the function is standalone.
            if (self == null && StaticReturnValue.IsGeneric() && Parameters.Any(p => p.IsGeneric))
            {
                return(null); // Evaluate standalone generic with arguments instead.
            }
            if (!(self is IPythonClassType selfClassType))
            {
                return(StaticReturnValue);
            }

            var returnType = StaticReturnValue.GetPythonType();

            switch (returnType)
            {
            case PythonClassType cls when cls.IsGeneric():
                // -> A[_T1, _T2, ...]
                // Match arguments
                IReadOnlyList <IPythonType> typeArgs = null;

                var classGenericParameters = selfClassType.GenericParameters.Keys.ToArray();
                if (classGenericParameters.Length > 0)
                {
                    // Declaring class is specific and provides definitions of generic parameters
                    typeArgs = classGenericParameters
                               .Select(n => selfClassType.GenericParameters.TryGetValue(n, out var t) ? t : null)
                               .ExcludeDefault()
                               .ToArray();
                }
                else
                {
                    typeArgs = ExpressionEval.GetTypeArgumentsFromParameters(this, args);
                }

                if (typeArgs != null)
                {
                    var specificReturnValue = cls.CreateSpecificType(new ArgumentSet(typeArgs));
                    return(new PythonInstance(specificReturnValue));
                }
                break;

            case IGenericTypeDefinition gtp1: {
                // -> _T
                if (selfClassType.GenericParameters.TryGetValue(gtp1.Name, out var specificType))
                {
                    return(new PythonInstance(specificType));
                }
                // Try returning the constraint
                // TODO: improve this, the heuristic is pretty basic and tailored to simple func(_T) -> _T
                var name       = StaticReturnValue.GetPythonType()?.Name;
                var typeDefVar = DeclaringModule.Analysis.GlobalScope.Variables[name];
                if (typeDefVar?.Value is IGenericTypeDefinition gtp2)
                {
                    // See if the instance (self) type satisfies one of the constraints.
                    return(selfClassType.Mro.Any(b => gtp2.Constraints.Any(c => c.Equals(b)))
                                ? selfClassType
                                : gtp2.Constraints.FirstOrDefault());
                }

                break;
            }
            }
            return(StaticReturnValue);
        }
コード例 #3
0
 public IMember Call(IPythonInstance instance, string memberName, IArgumentSet args) => GetMember(memberName);
コード例 #4
0
        public static IMember ListOfStrings(IPythonModule module, IPythonFunctionOverload overload, IArgumentSet argSet)
        {
            var type = new TypingListType("List", module.Interpreter.GetBuiltinType(BuiltinTypeId.Str), module.Interpreter, false);

            return(new TypingList(type));
        }
コード例 #5
0
        public static IMember Next(IPythonModule module, IPythonFunctionOverload overload, IArgumentSet argSet)
        {
            var args = argSet.Values <IMember>();

            return(args.Count > 0 && args[0] is IPythonIterator it ? it.Next : null);
        }
コード例 #6
0
        public static IMember Identity(IPythonModule module, IPythonFunctionOverload overload, IArgumentSet argSet)
        {
            var args = argSet.Values <IMember>();

            return(args.Count > 0 ? args.FirstOrDefault(a => !a.IsUnknown()) ?? args[0] : null);
        }
コード例 #7
0
        public static IMember Iterator(IPythonModule module, IPythonFunctionOverload overload, IArgumentSet argSet)
        {
            var args = argSet.Values <IMember>();

            if (args.Count > 0)
            {
                if (args[0] is IPythonCollection seq)
                {
                    return(seq.GetIterator());
                }
                var t = args[0].GetPythonType();
                if (t.IsBuiltin && t.Name == "str")
                {
                    return(new PythonTypeIterator(BuiltinTypeId.StrIterator, BuiltinTypeId.Str, module.Interpreter));
                }
            }
            return(null);
        }
コード例 #8
0
        public static IMember Open(IPythonModule declaringModule, IPythonFunctionOverload overload, IArgumentSet argSet)
        {
            var mode = argSet.GetArgumentValue <IPythonConstant>("mode");

            var bytes = false;

            if (mode != null)
            {
                var modeString = mode.GetString();
                bytes = modeString != null && modeString.Contains("b");
            }

            var io     = declaringModule.Interpreter.ModuleResolution.GetImportedModule("io");
            var ioBase = io?.GetMember(bytes ? "BufferedIOBase" : "TextIOWrapper")?.GetPythonType();

            return(ioBase != null ? new PythonInstance(ioBase) : null);
        }
コード例 #9
0
 public IMember Call(string memberName, IArgumentSet args) => Type;
コード例 #10
0
 public IMember CreateInstance(IArgumentSet args) => new PythonInstance(this);
コード例 #11
0
 public IMember Index(IPythonInstance instance, IArgumentSet args) => Interpreter.UnknownType;
コード例 #12
0
 public virtual IMember Index(IPythonInstance instance, IArgumentSet args)
 => InnerType.Index(instance, args);
コード例 #13
0
 public virtual IMember Call(IPythonInstance instance, string memberName, IArgumentSet args)
 => InnerType.Call(instance, memberName, args);
コード例 #14
0
 public virtual IMember CreateInstance(string typeName, IArgumentSet args)
 => IsAbstract ? null : InnerType.CreateInstance(typeName, args);
コード例 #15
0
        public static IMember CollectionItem(IPythonModule module, IPythonFunctionOverload overload, IArgumentSet argSet)
        {
            var args = argSet.Values <IMember>();

            return(args.Count > 0 && args[0] is PythonCollection c?c.Contents.FirstOrDefault() : null);
        }
コード例 #16
0
 public IMember Index(IArgumentSet args) => Type;
コード例 #17
0
        public static IMember Open(IPythonModule declaringModule, IPythonFunctionOverload overload, IArgumentSet argSet)
        {
            var mode = argSet.GetArgumentValue <IPythonConstant>("mode");

            var binary    = false;
            var writable  = false;
            var readWrite = false;

            var modeString = mode?.GetString();

            if (modeString != null)
            {
                binary    = modeString.Contains("b");
                writable  = modeString.Contains("w") || modeString.Contains("a") || modeString.Contains("x");
                readWrite = writable && modeString.Contains("r");
            }

            string returnTypeName;
            var    io = declaringModule.Interpreter.ModuleResolution.GetImportedModule("io");

            if (binary)
            {
                returnTypeName = writable ?
                                 readWrite ? "BufferedRandom" : "BufferedWriter"
                    : "BufferedReader";
            }
            else
            {
                returnTypeName = "TextIOWrapper";
            }

            var returnType = io?.GetMember(returnTypeName)?.GetPythonType();

            return(returnType != null ? new PythonInstance(returnType) : null);
        }
コード例 #18
0
 public static IReadOnlyList <T> Values <T>(this IArgumentSet args)
 => args.Arguments.Select(a => a.Value).OfType <T>().ToArray();
コード例 #19
0
        public static IMember TypeInfo(IPythonModule module, IPythonFunctionOverload overload, IArgumentSet argSet)
        {
            var args = argSet.Values <IMember>();

            return(args.Count > 0 ? args[0].GetPythonType() : module.Interpreter.GetBuiltinType(BuiltinTypeId.Type));
        }
コード例 #20
0
 public static IReadOnlyList <KeyValuePair <string, T> > Arguments <T>(this IArgumentSet args) where T : class
 => args.Arguments.Select(a => new KeyValuePair <string, T>(a.Name, a.Value as T)).ToArray();
コード例 #21
0
 public static IMember List(IPythonInterpreter interpreter, IPythonFunctionOverload overload, IArgumentSet argSet)
 => PythonCollectionType.CreateList(interpreter, argSet);
コード例 #22
0
 public static T Argument <T>(this IArgumentSet args, int index) where T : class
 => args.Arguments[index].Value as T;
コード例 #23
0
        public static IMember DictStringToObject(IPythonModule module, IPythonFunctionOverload overload, IArgumentSet argSet)
        {
            var str  = module.Interpreter.GetBuiltinType(BuiltinTypeId.Str);
            var obj  = module.Interpreter.GetBuiltinType(BuiltinTypeId.Object);
            var type = new TypingDictionaryType("Dict", str, obj, module.Interpreter, false);

            return(new TypingDictionary(type));
        }
コード例 #24
0
 /// <summary>
 /// Create instance of the type, if any.
 /// </summary>
 /// <param name="typeName">Name of the type. Used in specialization scenarios
 /// where constructor may want to create specialized type.</param>
 /// <param name="args">Any custom arguments required to create the instance.</param>
 public virtual IMember CreateInstance(string typeName, IArgumentSet args) => new PythonInstance(this);
コード例 #25
0
        public static IMember Range(IPythonModule module, IPythonFunctionOverload overload, IArgumentSet argSet)
        {
            var args = argSet.Values <IMember>();

            if (args.Count > 0)
            {
                var type = new PythonCollectionType(null, BuiltinTypeId.List, module.Interpreter, false);
                return(new PythonCollection(type, new[] { args[0] }));
            }
            return(null);
        }
コード例 #26
0
 /// <summary>
 /// Invokes method or property on the specified instance.
 /// </summary>
 /// <param name="instance">Instance of the type.</param>
 /// <param name="memberName">Member name to call, if applicable.</param>
 /// <param name="argSet">Call arguments.</param>
 public virtual IMember Call(IPythonInstance instance, string memberName, IArgumentSet argSet)
 => instance?.Call(memberName, argSet) ?? UnknownType;
コード例 #27
0
 public IMember CreateInstance(string typeName, IArgumentSet args) => this;
コード例 #28
0
 /// <summary>
 /// Invokes indexer on the specified instance.
 /// </summary>
 /// <param name="instance">Instance of the type.</param>
 /// <param name="index">Index arguments.</param>
 public virtual IMember Index(IPythonInstance instance, IArgumentSet args) => instance?.Index(args) ?? UnknownType;
コード例 #29
0
 public virtual IMember Call(IPythonInstance instance, string memberName, IArgumentSet args) => DeclaringModule.Interpreter.UnknownType;
コード例 #30
0
 public override IMember CreateInstance(string typeName, IArgumentSet args) => new TypingList(this);