/// <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);
        }
示例#2
0
        /// <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);
        }
示例#3
0
        /// <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);
        }
示例#4
0
 /// <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);
        }