/*
         * /// <summary>
         * /// Check if the type can make an arithmetic operation.
         * /// </summary>
         * /// <param name="operand">WriteType expression of the operand of binary expression.</param>
         * /// <param name="op">Operator.</param>
         * /// <param name="methodAnalyzed">The method that is being analyzed when the operation is performed.</param>
         * /// <param name="showErrorMessage">Indicates if an error message should be shown (used for dynamic types)</param>
         * /// <param name="fileName">File name.</param>
         * /// <param name="line">Line number.</param>
         * /// <param name="column">Column number.</param>
         * /// <returns>WriteType obtained with the operation.</returns>
         * public override TypeExpression Arithmetic(TypeExpression operand, Enum op, MethodType methodAnalyzed, bool showErrorMessage, Location loc) {
         *  if (this.fieldType != null)
         *      return this.fieldType.Arithmetic(operand, op, methodAnalyzed, showErrorMessage, loc);
         *  return null;
         * }
         *
         * /// <summary>
         * /// Check if the type can make an arithmetic operation.
         * /// </summary>
         * /// <param name="op">Operator.</param>
         * /// <param name="methodAnalyzed">The method that is being analyzed when the operation is performed.</param>
         * /// <param name="showErrorMessage">Indicates if an error message should be shown (used for dynamic types)</param>
         * /// <param name="fileName">File name.</param>
         * /// <param name="line">Line number.</param>
         * /// <param name="column">Column number.</param>
         * /// <returns>WriteType obtained with the operation.</returns>
         * public override TypeExpression Arithmetic(UnaryOperator op, MethodType methodAnalyzed, bool showErrorMessage, Location loc) {
         *  return this.fieldType.Arithmetic(op, methodAnalyzed, showErrorMessage, loc);
         * }
         */
        #endregion


        // WriteType Unification

        #region Unify
        /// <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)
        {
            FieldType ft = te as FieldType;

            if (ft != null)
            {
                bool success = this.fieldType.Unify(ft.fieldType, unification, previouslyUnified);
                if (success) // * Dynamic type
                {
                    DynVarOptions.Instance.AssignDynamism(this, ft.isDynamic);
                }
                // * 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));
            }
            if (te is ClassType && unification == SortOfUnification.Equivalent)
            {
                return(te.Unify(this, unification, previouslyUnified));
            }
            if (te.IsValueType() && unification == SortOfUnification.Equivalent)
            {
                return(te.Unify(this, unification, previouslyUnified));
            }
            return(false);
        }
Exemple #2
0
        private List <TypeExpression> GetTypes(TypeExpression typeExpression, bool includeTypeVariables, IDictionary <string, TypeExpression> evaluated = null)
        {
            List <TypeExpression> typeSet = new List <TypeExpression>();

            if (evaluated == null)
            {
                evaluated = new Dictionary <string, TypeExpression>();
            }
            if (evaluated.Keys.Contains(typeExpression.FullName))
            {
                if (evaluated[typeExpression.FullName] is ClassType)
                {
                    MergeClassType((ClassType)evaluated[typeExpression.FullName], (ClassType)typeExpression);
                }
                return(typeSet);
            }
            else
            {
                evaluated.Add(typeExpression.FullName, typeExpression);
            }
            if (typeExpression is UnionType)
            {
                UnionType union = typeExpression as UnionType;
                foreach (var expression in union.TypeSet)
                {
                    typeSet.AddRange(GetTypes(expression, includeTypeVariables, evaluated));
                }
            }
            else if (typeExpression.IsValueType() || typeExpression is StringType)
            {
                if (typeExpression is TypeVariable)
                {
                    typeSet.Add(((TypeVariable)typeExpression).Substitution);
                }
                else
                {
                    typeSet.Add(typeExpression);
                }
            }
            else if (typeExpression is TypeVariable)
            {
                if (((TypeVariable)typeExpression).Substitution != null)
                {
                    typeSet.AddRange(GetTypes(((TypeVariable)typeExpression).Substitution, includeTypeVariables, evaluated));
                }
                else if (includeTypeVariables)
                {
                    typeSet.Add(typeExpression);
                }
            }
            else if (typeExpression is FieldType)
            {
                FieldType fieldType = typeExpression as FieldType;
                typeSet.AddRange(GetTypes(fieldType.FieldTypeExpression, includeTypeVariables, evaluated));
            }
            else if (typeExpression is PropertyType)
            {
                PropertyType propertyType = typeExpression as PropertyType;
                typeSet.AddRange(GetTypes(propertyType.PropertyTypeExpression, includeTypeVariables, evaluated));
            }
            else if (typeExpression is ClassType)
            {
                typeSet.Add(typeExpression);
            }

            return(typeSet);
        }