예제 #1
0
        public IMember Call(IArgumentSet args, IPythonType self)
        {
            if (!_fromAnnotation)
            {
                // First try supplied specialization callback.
                var rt = _returnValueProvider?.Invoke(args.Eval?.Module, this, args, default);
                if (!rt.IsUnknown())
                {
                    return(rt);
                }
                if (StaticReturnValue == null && !string.IsNullOrEmpty(_returnDocumentation) && FunctionDefinition?.ReturnAnnotation != null)
                {
                    // There is return documentation but no static return value.
                    // This may happen if function is inside module circular
                    // dependency loop. Try and re-evaluate now.
                    var returnValue = FunctionEvaluator.GetReturnValueFromAnnotation(args.Eval as ExpressionEval, FunctionDefinition.ReturnAnnotation);
                    if (returnValue != null)
                    {
                        SetReturnValue(returnValue, true);
                        return(returnValue);
                    }
                }
            }

            return(GetSpecificReturnType(self as IPythonClassType, args));
        }
 public IMember GetReturnValue(LocationInfo callLocation, IArgumentSet args)
 {
     if (!_fromAnnotation)
     {
         // First try supplied specialization callback.
         var rt = _returnValueProvider?.Invoke(_declaringModule, this, callLocation, args.Values <IMember>());
         if (!rt.IsUnknown())
         {
             return(rt);
         }
     }
     return(StaticReturnValue);
 }
        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);
                }
            }

            return(GetSpecificReturnType(self as IPythonClassType, args));
        }
예제 #4
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)
                {
                    return(gtp2.Constraints.FirstOrDefault());
                }

                break;
            }
            }
            return(StaticReturnValue);
        }