/// <summary> /// Infers the types of the given collection of named type arguments from the given collection /// of parameters. /// </summary> /// <param name="typeArgNames">The names of the type parameters.</param> /// <param name="parameters"></param> /// <returns></returns> public static IList <IBoundDecl> Infer(IEnumerable <string> typeParameters, IUnboundDecl parameterType, IBoundDecl argType) { var inferrer = new TypeArgInferrer(typeParameters); inferrer.mParamTypes.Push(parameterType); bool dummy = argType.Accept(inferrer); inferrer.mParamTypes.Pop(); // if the inference failed (like from a type collision) then fail if (inferrer.mFailed) { return(null); } // if any type argument is left unfilled then fail if (inferrer.mTypeArguments.Contains(null)) { return(null); } return(inferrer.mTypeArguments); }
public BindingContext BuildContext(BindingContext callingContext, IUnboundDecl parameterType, IBoundDecl argType, ref IEnumerable <IBoundDecl> typeArgs, out bool canInferArgs) { // try to infer the args if not passed in IList <IBoundDecl> inferredTypeArgs = TypeArgInferrer.Infer(TypeParameters, parameterType, argType); canInferArgs = inferredTypeArgs != null; if (canInferArgs) { typeArgs = inferredTypeArgs; } if (typeArgs.IsEmpty()) { typeArgs = null; } // include the open namespaces of the calling context. this was the instantiated // generic has access to everything that the instantiation call site has access // to var searchSpace = new NameSearchSpace(BaseType.SearchSpace, callingContext.SearchSpace); return(new BindingContext(callingContext.Compiler, searchSpace, TypeParameters, typeArgs)); }
//### bob: this is basically a copy from Struct :( public Union Instantiate(Compiler compiler, IEnumerable <IBoundDecl> typeArgs) { // look for a previously instantiated one var union = compiler.Types.FindUnion(BaseType.Name, typeArgs); if (union == null) { // instantiate the structure union = BaseType.Clone(typeArgs); // add it to the list of known types. this must happen before // the subsequent binding in case the type is recursive. compiler.Types.Add(union, typeArgs); // immediately bind it with the type arguments BindingContext context = new BindingContext(compiler, union.SearchSpace, TypeParameters, typeArgs); TypeBinder.Bind(context, union); // figure out which of the cases can infer type arguments. this // needs to be done now while we still know the type parameters // and the unbound uses of them in the cases. for (int i = 0; i < union.Cases.Count; i++) { var inferredTypeArgs = TypeArgInferrer.Infer(TypeParameters, BaseType.Cases[i].ValueType.Unbound, union.Cases[i].ValueType.Bound); union.Cases[i].HasInferrableTypeArguments = inferredTypeArgs != null; } } return(union); }