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)); }
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); }