/// <summary> /// Adds a new type expression. /// </summary> /// <param name="type">WriteType expression to add.</param> /// <returns>If the type has been added</returns> public bool AddType(TypeExpression type) { bool added = true; IntersectionType intersection = TypeExpression.As <IntersectionType>(type); if (intersection != null) { foreach (TypeExpression t in intersection.typeSet) { added = added && this.AddType(t); } this.ValidTypeExpression = false; return(added); } Predicate <TypeExpression> predicate = delegate(TypeExpression te2) { return((bool)te2.AcceptOperation(new EquivalentOperation(type), null)); }; if (this.typeSet.Find(predicate) == null) { this.typeSet.Add(type); this.ValidTypeExpression = false; return(true); } return(false); }
/// <summary> /// This method unifies two type expressions (this and te) /// </summary> /// <param name="te">The expression to be unfied with this</param> /// <param name="unification">Indicates if the kind of unification (equivalent, incremental or override).</param> /// <param name="previouslyUnified">To detect infinite loops. The previously unified pairs of type expressions.</param> /// <returns>If the unification was successful</returns> public override bool Unify(TypeExpression te, SortOfUnification unification, IList <Pair <TypeExpression, TypeExpression> > previouslyUnified) { InterfaceType it = TypeExpression.As <InterfaceType>(te); if (it != null) { bool success = (bool)this.AcceptOperation(new EquivalentOperation(it), null); // * Clears the type expression cache this.ValidTypeExpression = false; te.ValidTypeExpression = false; return(success); } if (te is TypeVariable && unification != SortOfUnification.Incremental) { // * No incremental unification is commutative return(te.Unify(this, unification, previouslyUnified)); } return(false); }
/// <summary> /// Returns true if the union type contains method types and this methods returns differents types. (At least, one valut type). /// </summary> /// <returns>True if the union type contains method types and this methods returns differents types. Otherwise, false.</returns> public bool ContainsDifferentReturns() { TypeExpression current = null; TypeExpression aux = null; for (int i = 0; i < this.typeSet.Count; i++) { if (this.typeSet[i] is TypeVariable) { return(true); } MethodType mt = null; if ((mt = TypeExpression.As <MethodType>(this.typeSet[i])) != null) { current = mt.Return; if (aux != null && aux != current) // This comparation searches differents value types. { return(true); } aux = current; } } return(false); }
/// <summary> /// Tells if a type expression is a type or a type variable /// unified to a type /// </summary> /// <typeparam name="T">A concrete type expression</typeparam> /// <param name="type">The general type expression</param> /// <returns>If the type is the expected one</returns> public static bool Is <T>(TypeExpression type) where T : TypeExpression { return(TypeExpression.As <T>(type) != null); }
// WriteType inference #region overloadResolution() /// <summary> /// A public method for being used as a global overload resolution process /// </summary> /// <param name="arguments">The ordered types of actual parameters</param> /// <param name="fileName"></param> /// <param name="line"></param> /// <param name="column"></param> /// <returns>The actual method called (a union type if more than one is suitable)</returns> public TypeExpression overloadResolution(TypeExpression[] arguments, Location location) { int aux; int min = -1, index = -1, minNumFreeVariables = Int32.MaxValue; // * We create a dictionary of <index,promotionValue> to remember the promotion values (they could have // repeated values because of type variables) Dictionary <int, int> promotionValues = new Dictionary <int, int>(); if (this.typeSet.Count == 0) { System.Diagnostics.Debug.Assert(false, "There should be no empty intersection types."); return(null); } for (int i = 0; i < this.typeSet.Count; i++) { MethodType mt = TypeExpression.As <MethodType>(this.typeSet[i]); if (mt == null) { ErrorManager.Instance.NotifyError(new OperationNotAllowedError("()", mt.FullName, location)); } aux = mt.Promotion(arguments, location); if (aux != -1) { if ((min >= aux) || (min == -1)) { min = aux; index = i; promotionValues[index] = min; } } } // * No method is suitable if (index == -1) { ErrorManager.Instance.NotifyError(new UnknownMemberError(location)); return(null); } index = -1; // * Gets the min number of free variables foreach (KeyValuePair <int, int> pair in promotionValues) { if (pair.Value == min) { aux = ((MethodType)this.typeSet[pair.Key]).GetNumberFreeVariables(); if (aux < minNumFreeVariables) { minNumFreeVariables = aux; } } } // * Assigns a union of all the best methods TypeExpression bestMethods = null; foreach (KeyValuePair <int, int> pair in promotionValues) { if (pair.Value == min && ((MethodType)this.typeSet[pair.Key]).GetNumberFreeVariables() == minNumFreeVariables) { bestMethods = UnionType.collect(bestMethods, this.typeSet[pair.Key]); } } // * We've got'em return(bestMethods); }