/// <summary> /// Given generic type and list of arguments in the expression like /// Mapping[T1, int, ...] or Mapping[str, int] where Mapping inherits from Generic[K,T] creates generic class base /// (if the former) on specific type (if the latter). /// </summary> private IMember CreateSpecificTypeFromIndex(IGenericType gt, IReadOnlyList <IMember> args, Expression expr) { // TODO: move check to GenericClassBase. This requires extensive changes to SpecificTypeConstructor. if (gt.Name.EqualsOrdinal("Generic")) { var genericTypeArgs = args.OfType <IGenericTypeParameter>().ToArray(); if (!GenericClassParameterValid(genericTypeArgs, args, expr)) { return(UnknownType); } // Generic[T1, T2, ...] expression. Create generic base for the class. return(new GenericClassBase(genericTypeArgs, Module.Interpreter)); } // For other types just use supplied arguments return(args.Count > 0 ? gt.CreateSpecificType(new ArgumentSet(args, expr, this)) : UnknownType); }
private async Task <IMember> CreateSpecificFromGenericAsync(IGenericType gen, IndexExpression expr, CancellationToken cancellationToken = default) { var args = new List <IPythonType>(); if (expr.Index is TupleExpression tex) { foreach (var item in tex.Items) { var e = await GetValueFromExpressionAsync(item, cancellationToken); args.Add(e?.GetPythonType() ?? UnknownType); } } else { var index = await GetValueFromExpressionAsync(expr.Index, cancellationToken); args.Add(index?.GetPythonType() ?? UnknownType); } return(gen.CreateSpecificType(args, Module, GetLoc(expr))); }
/// <summary> /// Given generic type and list of arguments in the expression like /// Mapping[T1, int, ...] or Mapping[str, int] where Mapping inherits from Generic[K,T] creates generic class base /// (if the former) on specific type (if the latter). /// </summary> private IMember CreateSpecificTypeFromIndex(IGenericType gt, IReadOnlyList <IMember> args, Expression expr) { if (gt.Name.EqualsOrdinal("Generic")) { var genericTypeArgs = args.OfType <IGenericTypeParameter>().ToArray(); if (!GenericClassParameterValid(genericTypeArgs, args, expr)) { return(UnknownType); } // Generic[T1, T2, ...] expression. Create generic base for the class. return(new GenericClassParameter(genericTypeArgs, Module)); } // For other types just use supplied arguments if (args.Count > 0) { return(gt.CreateSpecificType(new ArgumentSet(args, expr, this))); } return(UnknownType); }
/// <summary> /// Given generic type and list of indices in the expression like /// Generic[T1, T2, ...] or List[str] creates generic class base /// (if the former) on specific type (if the latter). /// </summary> private IMember CreateSpecificTypeFromIndex(IGenericType gt, IReadOnlyList <IMember> indices, Expression expr) { // See which ones are generic parameters as defined by TypeVar() // and which are specific types. Normally there should not be a mix. var genericTypeArgs = indices.OfType <IGenericTypeDefinition>().ToArray(); var specificTypes = indices.Where(i => !(i is IGenericTypeDefinition)).OfType <IPythonType>().ToArray(); if (genericTypeArgs.Length > 0 && genericTypeArgs.Length != indices.Count) { // TODO: report that some type arguments are not declared with TypeVar. } if (specificTypes.Length > 0 && specificTypes.Length != indices.Count) { // TODO: report that arguments are not specific types or are not declared. } if (gt.Name.EqualsOrdinal("Generic")) { // Generic[T1, T2, ...] expression. Create generic base for the class. if (genericTypeArgs.Length > 0) { return(new GenericClassParameter(genericTypeArgs, Module)); } else { // TODO: report too few type arguments for Generic[]. return(UnknownType); } } // For other types just use supplied arguments if (indices.Count > 0) { return(gt.CreateSpecificType(new ArgumentSet(indices))); } // TODO: report too few type arguments for the generic expression. return(UnknownType); }