Exemple #1
0
 /// <summary>
 /// Returns true if the union type contains the specified value type.
 /// </summary>
 /// <param name="type">WriteType expression to search.</param>
 /// <returns>True if the union type contains the specified type expression. Otherwise, false.</returns>
 public bool ContainsValueType(TypeExpression type)
 {
     for (int i = 0; i < this.typeSet.Count; i++)
     {
         if (this.typeSet[i].IsValueType())
         {
             if (this.typeSet[i] == type)
             {
                 return(true);
             }
         }
     }
     return(false);
 }
        ///// <summary>
        ///// Check if the type can make an assignment 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="unification">Indicates if the kind of unification (equivalent, incremental or override).</param>
        ///// <param name="actualImplicitObject">Only suitable when the assignment is executed as a constraint of a method call. In that case,
        ///// this parameter represents the actual object used to pass the message; null otherwise.</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 Assignment(TypeExpression operand, AssignmentOperator op, MethodType methodAnalyzed, SortOfUnification unification,
        //            TypeExpression actualImplicitObject, Location location) {
        //    if (op == AssignmentOperator.Assign) {
        //        if (operand.Promotion(this, op, methodAnalyzed, location) == null)
        //            return null;
        //        if (!this.HasTypeVariables())
        //            return this;
        //        // * If the left expression of the assignment has type variables,
        //        //   we must return the concrete type (not the abstract one)
        //        // * Then whe unify the concrete types
        //        FieldType fieldType = TypeExpression.As<FieldType>(operand);
        //        if (fieldType != null)
        //            operand = fieldType.FieldTypeExpression;
        //        if (this.Unify(operand, unification, new List<Pair<TypeExpression, TypeExpression>>())) {
        //            this.ValidTypeExpression = false;
        //            return this;
        //        }
        //    }
        //    ErrorManager.Instance.NotifyError(new OperationNotAllowedError(op.ToString(), this.FullName, operand.FullName, location));
        //    return null;
        //}
        #endregion

        #region Dot() ANULADA
        ///// <summary>
        ///// Check if the type can make an operation of field access.
        ///// Generates an error if the attribute does not exist.
        ///// Generates a constraint in case it is applied to a free variable.
        ///// </summary>
        ///// <param name="field">Field to access.</param>
        ///// <param name="methodAnalyzed">The method that is being analyzed when the operation is performed.</param>
        ///// <param name="previousDot">To detect infinite loops. The types that have been previously passed the dot message. Used for union 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 Dot(string memberName, MethodType methodAnalyzed, IList<TypeExpression> previousDot, Location loc) {
        //    TypeExpression member = this.Dot(memberName, previousDot);
        //    if (member == null) {
        //        ErrorManager.Instance.NotifyError(new UnknownMemberError(memberName, loc));
        //        return null;
        //    }
        //    if (!validAccess(member)) {
        //        ErrorManager.Instance.NotifyError(new ProtectionLevelError(memberName, loc));
        //        return null;
        //    }
        //    return member;
        //}
        ///// <summary>
        ///// Tries to find a attribute.
        ///// No error is generated if the attribute does not exist.
        ///// It does not generate a constraint in case it is applied to a free variable.
        ///// </summary>
        ///// <param name="memberName">Member to access.</param>
        ///// <param name="previousDot">To detect infinite loops. The types that have been previously passed the dot message. Used for union types.</param>
        ///// <returns>WriteType obtained with the operation.</returns>
        //public override TypeExpression Dot(string memberName, IList<TypeExpression> previousDot) {
        //    if (this.Members.ContainsKey(memberName))
        //        return this.Members[memberName].WriteType;
        //    if (this.baseClass != null) // Search in inherit class
        //        return this.baseClass.Dot(memberName, previousDot);
        //    return null;
        //}
        /// <summary>
        /// Validates the correct access to members, taking into account the information hiding level.
        /// </summary>
        /// <param name="member">The type of the member</param>
        /// <returns>If the access has been correct</returns>
        public bool validAccess(TypeExpression member)
        {
            // * Union or Intersection type
            IList <TypeExpression> typeSet = null;
            UnionType unionType            = member as UnionType;

            if (member is UnionType)
            {
                typeSet = ((UnionType)member).TypeSet;
            }
            else if (member is IntersectionType)
            {
                typeSet = ((IntersectionType)member).TypeSet;
            }
            if (typeSet != null)
            {
                bool anyValid = false;
                foreach (TypeExpression type in typeSet)
                {
                    if (!this.validAccess(type) && !member.IsDynamic)
                    {
                        return(false);
                    }
                    else
                    {
                        anyValid = true;
                    }
                    return(anyValid);
                }
            }
            // * Member type
            IMemberType memberType = member as IMemberType;

            if (memberType == null || memberType.MemberInfo == null)
            {
                return(false);
            }
            // * Public or Internal
            if (memberType.MemberInfo.hasModifier(Modifier.Public) || memberType.MemberInfo.hasModifier(Modifier.Internal))
            {
                return(true);
            }
            // * Private
            if (memberType.MemberInfo.hasModifier(Modifier.Private))
            {
                return((bool)this.AcceptOperation(new EquivalentOperation(memberType.MemberInfo.Class), null));
            }
            // * Protected
            return((bool)this.AcceptOperation(new EquivalentOperation(memberType.MemberInfo.Class), null) || this.InheritsFrom(memberType.MemberInfo.Class));
        }
Exemple #3
0
        // WriteType Promotion

        #region Promotion()
        /// <summary>
        /// Requires the implicit object to be a subtype of the type parameter
        /// </summary>
        /// <param name="type">WriteType to promotion.</param>
        /// <param name="methodAnalyzed">The method that is being analyzed when the operation is performed.</param>
        /// <param name="op">An optional operator to report error messages.</param>
        /// <param name="fileName">File name.</param>
        /// <param name="line">Line number.</param>
        /// <param name="column">Column number.</param>
        /// <returns>The supertype; null if there has been some error.</returns>
        //public override TypeExpression Promotion(TypeExpression type, MethodType methodAnalyzed, Location loc) {
        //    return this.Promotion(type, AssignmentOperator.Assign, methodAnalyzed, loc);
        //}
        //public override TypeExpression Promotion(TypeExpression type, Enum op, MethodType methodAnalyzed, Location loc) {
        //    return this.InternalPromotion(type, op, methodAnalyzed, loc);
        //}
        //private TypeExpression InternalPromotion(TypeExpression superType, Enum op, MethodType methodAnalyzed, Location loc) {
        //    if (this.IsFreshVariable() && methodAnalyzed != null) {
        //        // * A constraint is added to the method analyzed
        //        PromotionConstraint constraint = new PromotionConstraint(this, superType, op, loc);
        //        methodAnalyzed.AddConstraint(constraint);
        //        return superType;
        //    }
        //    // * Static Behaviour: All the types in typeset must promote
        //    // * Dynamic Behaviour: One of the types in typeset must promote
        //    int aux = 0;
        //    UnionType dynamicUnionType = new UnionType();
        //    dynamicUnionType.isDynamic = true;
        //    foreach (TypeExpression subType in this.typeSet) {
        //        if (this.IsDynamic) {
        //            // * Dynamic
        //            if (subType.IsFreshVariable())
        //                dynamicUnionType.AddType(subType);
        //            else {
        //                aux = (int) subType.AcceptOperation(new PromotionLevelOperation(superType));
        //                if (aux != -1)
        //                    return superType;
        //            }
        //        }
        //        if (!this.IsDynamic) {
        //            // * Static
        //            aux = (int)subType.AcceptOperation(new PromotionLevelOperation(superType));
        //            if (aux == -1) {
        //                ErrorManager.Instance.NotifyError(new TypePromotionError(this.FullName, superType.FullName, op.ToString(), loc));
        //                return null;
        //            }
        //        }
        //    }
        //    if (dynamicUnionType.Count != 0) {
        //        // * If the union type is dynamic and no type in the type set promotes, then we generate a constraint with one promotion grouping the fresh types in the type set
        //        PromotionConstraint constraint = new PromotionConstraint(dynamicUnionType, superType, op, loc);
        //        methodAnalyzed.AddConstraint(constraint);
        //        return superType;
        //    }
        //    if (this.IsDynamic && aux == -1) {
        //        // * No promotion at all
        //        ErrorManager.Instance.NotifyError(new TypePromotionError(this.FullName, superType.FullName, op.ToString(), loc));
        //        return null;
        //    }
        //    return superType;
        //}
        #endregion

        #region SuperType()
        /// <summary>
        /// The opposite of the promotion method. Indicates if the parameter
        /// promotes to the implicit object
        /// T1 <= T1\/T2
        /// T2 <= T1\/T2
        /// </summary>
        /// <param name="type">WriteType to promotion.</param>
        /// <returns>Returns a promotion value.</returns>
        public int SuperType(TypeExpression subType)
        {
            // * Takes the lower promotion level (except -1)
            int lowerLevelOfPromotion = Int32.MaxValue;

            foreach (TypeExpression superType in this.typeSet)
            {
                int aux = (int)subType.AcceptOperation(new PromotionLevelOperation(superType), null);
                if (aux != -1 && aux < lowerLevelOfPromotion)
                {
                    lowerLevelOfPromotion = aux;
                }
            }
            return(lowerLevelOfPromotion == Int32.MaxValue ? -1 : lowerLevelOfPromotion);
        }
Exemple #4
0
        // WriteType Promotion

        #region PromotionLevel() ANULADA
        ///// <summary>
        ///// Returns a value that indicates a promotion level.
        ///// </summary>
        ///// <param name="type">WriteType to promotion.</param>
        ///// <returns>Returns a promotion value.</returns>
        //public override int PromotionLevel(TypeExpression type) {
        //    // * Bool type and type variable
        //    if (TypeExpression.As<BoolType>(type)!=null)
        //        return 0;
        //    // * WriteType variable
        //    TypeVariable typeVariable = type as TypeVariable;
        //    if (typeVariable != null && typeVariable.Substitution==null)
        //        // * A free variable is complete promotion
        //        return 0;
        //    // * Union type
        //    UnionType unionType = TypeExpression.As<UnionType>(type);
        //    if (unionType != null)
        //        return unionType.SuperType(this);
        //    // * Field type and bounded type variable
        //    FieldType fieldType = TypeExpression.As<FieldType>(type);
        //    if (fieldType != null)
        //        return this.PromotionLevel(fieldType.FieldTypeExpression);
        //    // * Use the BCL object oriented approach
        //    return this.BCLType.PromotionLevel(type);
        //}

        #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)
        {
            BoolType bt = te as BoolType;

            if (bt != null)
            {
                return(true);
            }
            if (te is TypeVariable && unification != SortOfUnification.Incremental)
            {
                // * No incremental unification is commutative
                return(te.Unify(this, unification, previouslyUnified));
            }
            return(false);
        }
Exemple #5
0
        /// <summary>
        /// Adds a type variable to the object's equivalence class
        /// </summary>
        /// <param name="typeExpression">The type variable to add</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 type variable has been actually added</returns>
        /// EN esta clase se le ha cambiado su visibilidad
        internal bool addToMyEquivalenceClass(TypeExpression typeExpression, SortOfUnification unification, IList <Pair <TypeExpression, TypeExpression> > previouslyUnified)
        {
            // * It the type variable does not have a equivalence class, we create it
            if (this.equivalenceClass == null)
            {
                this.equivalenceClass = new EquivalenceClass(this);
            }
            bool added = this.equivalenceClass.add(typeExpression, unification, previouslyUnified);

            this.ValidTypeExpression = false;
            if (typeExpression is TypeVariable)
            {
                typeExpression.ValidTypeExpression = false;
            }
            return(added);
        }
Exemple #6
0
        // 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)
        {
            // * Infinite recursion detection
            Pair <TypeExpression, TypeExpression> pair = new Pair <TypeExpression, TypeExpression>(this, te);

            if (previouslyUnified.Contains(pair))
            {
                return(true);
            }
            previouslyUnified.Add(pair);

            bool      success = false;
            ArrayType at      = te as ArrayType;

            if (at != null)
            {
                success = this.arrayType.Unify(at.arrayType, unification, previouslyUnified);
            }
            else if (te is TypeVariable)
            {
                TypeVariable typeVariable = (TypeVariable)te;
                if (unification != SortOfUnification.Incremental)
                {
                    // * Incremental is commutative
                    success = typeVariable.Unify(this, unification, previouslyUnified);
                }
                else   // * Array(var) should unify to Var=Array(int)
                {
                    if (typeVariable.Substitution != null)
                    {
                        success = this.Unify(typeVariable.Substitution, unification, previouslyUnified);
                    }
                    else
                    {
                        success = false;
                    }
                }
            }
            else if (te is UnionType)
            {
                success = te.Unify(this, unification, previouslyUnified);
            }
            // * Clears the type expression cache
            this.ValidTypeExpression = false;
            te.ValidTypeExpression   = false;
            return(success);
        }
        /// <summary>
        /// Check if the type can make a method operation.
        /// </summary>
        /// <param name="actualImplicitObject">The actual implicit object employed to pass the message</param>
        /// <param name="arguments">Arguments of the method.</param>
        /// <param name="methodAnalyzed">The method that is being analyzed when the operation is performed.</param>
        /// <param name="activeSortOfUnification">The active sort of unification used (Equivalent is the default
        /// one and Incremental is used in the SSA bodies of the while, for and do statements)</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 Parenthesis(TypeExpression actualImplicitObject, TypeExpression[] arguments, MethodType methodAnalyzed,
        //                    SortOfUnification activeSortOfUnification, Location loc) {
        //    TypeExpression method = overloadResolution(arguments, loc);
        //    if (method == null)
        //        return null;
        //    return method.Parenthesis(actualImplicitObject, arguments, methodAnalyzed, activeSortOfUnification, 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)
        {
            // * Infinite recursion detection
            Pair <TypeExpression, TypeExpression> pair = new Pair <TypeExpression, TypeExpression>(this, te);

            if (previouslyUnified.Contains(pair))
            {
                return(true);
            }
            previouslyUnified.Add(pair);

            // * Clears the type expression cache
            this.ValidTypeExpression = false;
            te.ValidTypeExpression   = false;
            // TODO
            return(false);
        }
Exemple #8
0
        /// <summary>
        /// Replaces type variables substituting the old type variables for the new ones.
        /// </summary>
        /// <param name="typeVariableMappings">Each new type varaiable represent a copy of another existing one.
        /// This parameter is a mapping between them, wher tmpName=old and value=new.</param>
        public override void ReplaceTypeVariables(IDictionary <TypeVariable, TypeVariable> typeVariableMappings)
        {
            TypeVariable fieldTypeVariable = this.fieldType as TypeVariable;

            if (fieldTypeVariable == null)
            {
                if (this.fieldType.HasTypeVariables())
                {
                    this.fieldType.ReplaceTypeVariables(typeVariableMappings);
                }
                return;
            }
            if (typeVariableMappings.ContainsKey(fieldTypeVariable))
            {
                this.fieldType = typeVariableMappings[fieldTypeVariable];
            }
            this.ValidTypeExpression = false;
        }
        /// <summary>
        /// Method that clones each type variable of a type expression.
        /// Equivalence classes are not cloned (but included in the equivalenceClasses parameter.
        /// The default implementation is do nothing (for built-in types).
        /// </summary>
        /// <param name="typeVariableMappings">Each new type varaiable represent a copy of another existing one.
        /// This parameter is a mapping between them, wher tmpName=old and value=new.
        /// If the variable to be cloned already has a map, we return the latter.</param>
        /// <param name="equivalenceClasses">Each equivalence class of all the type variables.</param>
        /// <param name="clonedClasses">This parameter collects the set of all cloned classes. It is used to detect infinite recursion.</param>
        /// <returns>The new type expression (itself by default)</returns>
        public override TypeExpression CloneTypeVariables(IDictionary <TypeVariable, TypeVariable> typeVariableMappings, IList <EquivalenceClass> equivalenceClasses, IList <ClassType> clonedClasses)
        {
            // * If the variable to be cloned already has a map, we return the latter
            if (typeVariableMappings.ContainsKey(this))
            {
                return(typeVariableMappings[this]);
            }
            TypeVariable newOne = TypeVariable.NewTypeVariable;

            newOne.IsDynamic = this.IsDynamic;
            // * Sets the mapping between the old and new one in the typeVariableMappings parameter
            typeVariableMappings[this] = newOne;
            EquivalenceClass clonedEquivalenceClass = null;

            if (this.EquivalenceClass != null)
            {
                clonedEquivalenceClass = new EquivalenceClass();
                foreach (var typeVariable in this.EquivalenceClass.TypeVariables)
                {
                    TypeExpression clonedTypeVariable = typeVariable.Value.CloneType(typeVariableMappings);
                    clonedEquivalenceClass.add(clonedTypeVariable, SortOfUnification.Equivalent, new List <Pair <TypeExpression, TypeExpression> >());
                }
            }

            // * Add both equivalence classes to the equivalenceClasses parameter
            if (clonedEquivalenceClass != null && !equivalenceClasses.Contains(clonedEquivalenceClass))
            {
                equivalenceClasses.Add(clonedEquivalenceClass);
            }
            // * Assigns a clone of the substitution when it previously exists
            if (this.Substitution != null)
            {
                TypeExpression clonedSubstitution = this.Substitution.CloneTypeVariables(typeVariableMappings, equivalenceClasses, clonedClasses);
                newOne.addToMyEquivalenceClass(clonedSubstitution, SortOfUnification.Equivalent, new List <Pair <TypeExpression, TypeExpression> >());
            }
            else if (clonedEquivalenceClass != null)
            {
                newOne.equivalenceClass = clonedEquivalenceClass;
            }
            newOne.ValidTypeExpression = false;
            // * Returns the new type variable
            return(newOne);
        }
        /// <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);
        }
        // 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)
        {
            DoubleType dt = te as DoubleType;

            if (dt != null)
            {
                return(true);
            }
            if (te is TypeVariable && unification != SortOfUnification.Incremental)
            {
                // * No incremental unification is commutative
                return(te.Unify(this, unification, previouslyUnified));
            }
            if (te is FieldType && unification == SortOfUnification.Equivalent)
            {
                return(((FieldType)te).FieldTypeExpression.Unify(this, unification, previouslyUnified));
            }
            return(false);
        }
Exemple #12
0
        // Helper Methods

        #region IsConcreteType()
        /// <summary>
        /// Tells if the parameter is a concrete class type
        /// </summary>
        /// <param name="actualImplicitObject">The object's type</param>
        /// <returns>The appropriate class type if the parameter is a concret object</returns>
        public static ClassType IsConcreteType(TypeExpression actualImplicitObject)
        {
            TypeVariable typeVariable = actualImplicitObject as TypeVariable;

            if (typeVariable != null)
            {
                actualImplicitObject = typeVariable.Substitution;
            }
            ClassType classType = actualImplicitObject as ClassType;

            if (classType != null && classType.ConcreteType)
            {
                return(classType);
            }
            UnionType unionType = actualImplicitObject as UnionType;

            if (unionType != null && unionType.Count > 0)
            {
                return(IsConcreteType(unionType.TypeSet[0]));
            }
            return(null);
        }
Exemple #13
0
        ///// <summary>
        ///// Check if the type can make an operation of field access.
        ///// Generates an error if the attribute does not exist.
        ///// Generates a constraint in case it is applied to a free variable.
        ///// </summary>
        ///// <param name="field">Field to access.</param>
        ///// <param name="methodAnalyzed">The method that is being analyzed when the operation is performed.</param>
        ///// <param name="previousDot">To detect infinite loops. The types that have been previously passed the dot message. Used for union 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 Dot(string field, MethodType methodAnalyzed, IList<TypeExpression> previousDot, Location loc) {
        //    if (this.fieldType != null) {
        //        // * If the field type is a dynamic union type, so it is the union
        //        UnionType unionType = As<UnionType>(this.fieldType);
        //        if (unionType != null)
        //            DynVarOptions.Instance.AssignDynamism(this.fieldType, this.IsDynamic);
        //        return this.fieldType.Dot(field, methodAnalyzed, previousDot, loc);
        //    }
        //    return null;
        //}
        ///// <summary>
        ///// Tries to find a attribute.
        ///// No error is generated if the attribute does not exist.
        ///// It does not generate a constraint in case it is applied to a free variable.
        ///// </summary>
        ///// <param name="memberName">Member to access.</param>
        ///// <param name="previousDot">To detect infinite loops. The types that have been previously passed the dot message. Used for union types.</param>
        ///// <returns>WriteType obtained with the operation.</returns>
        //public override TypeExpression Dot(string memberName, IList<TypeExpression> previousDot) {
        //    if (this.fieldType != null)
        //        return this.fieldType.Dot(memberName, previousDot);
        //    return null;
        //}
        #endregion

        //#region Bracket() anulada

        ///// <summary>
        ///// Check if the type can make an array operation.
        ///// </summary>
        ///// <param name="index">TypeExpression of the index.</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 Bracket(TypeExpression index, MethodType methodAnalyzed, bool showErrorMessage, Location loc) {
        //    if (this.fieldType != null)
        //        return this.fieldType.Bracket(index, methodAnalyzed, showErrorMessage, loc);
        //    return null;
        //}

        //#endregion

        #region Assignment() ANULADA
        /// <summary>
        /// Check if the type can make an assignment 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="unification">Indicates if the kind of unification (equivalent, incremental or override).</param>
        /// <param name="actualImplicitObject">Only suitable when the assignment is executed as a constraint of a method call. In that case,
        /// this parameter represents the actual object used to pass the message; null otherwise.</param>
        /// <param name="location"> Location of the element</param>
        /// <returns>WriteType obtained with the operation.</returns>
        //public override TypeExpression Assignment(TypeExpression operand, AssignmentOperator op, MethodType methodAnalyzed, SortOfUnification unification,
        //            TypeExpression actualImplicitObject, Location location) {
        //    // * We check if a constraint must be generated. Is it an assignment of the implicit object's field?
        //    bool found = false;
        //    // * In case it has free variables and the reference used is this, we add a constraint to the method
        //    if (this.HasTypeVariables() && methodAnalyzed != null && ClassType.IsConcreteType(actualImplicitObject) == null) {
        //        // * They should be the same exact (sub)classes. This represent the same instance, not another instance of the same class.
        //        ClassType methodSuperClass = (ClassType)methodAnalyzed.MemberInfo.Class;
        //        while (!(found = (this.MemberInfo.Class == methodSuperClass)) && methodSuperClass != null)
        //            methodSuperClass = methodSuperClass.BaseClass;
        //        if (found) {
        //            // * An assignment constraint is added, postponing the type inference
        //            // * If an actual implicit object is used, we take its field's type
        //            FieldType fieldType = this;
        //            ClassType thisType = TypeExpression.As<ClassType>(actualImplicitObject);
        //            if (thisType == null) {
        //                FieldType field = TypeExpression.As<FieldType>(actualImplicitObject);
        //                if (field != null)
        //                    thisType = TypeExpression.As<ClassType>(field.FieldTypeExpression);
        //            }
        //            if (thisType != null)
        //                fieldType = (FieldType)thisType.Fields[this.MemberInfo.MemberIdentifier].WriteType;
        //            methodAnalyzed.AddConstraint(new FieldTypeAssignmentConstraint(fieldType, operand, unification));
        //            methodAnalyzed.ValidTypeExpression = false;
        //            return this.fieldType;
        //        }
        //    }
        //    if (!found && this.fieldType != null)
        //        return this.fieldType.Assignment(operand, op, null, unification, actualImplicitObject, location);
        //    return null;
        //}

        #endregion

        #region Arithmetic() >NUL>C>

        /*
         * /// <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

        #region Relational()ANULADA

        /*      /// <summary>
         * /// Check if the type can make an relational 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 Relational(TypeExpression operand, RelationalOperator op, MethodType methodAnalyzed, bool showErrorMessage, Location loc) {
         *  if (this.fieldType != null)
         *      return this.fieldType.Relational(operand, op, methodAnalyzed, showErrorMessage, loc);
         *  return null;
         * }
         *
         */
        #endregion

        #region PromotionLevl()-->#        /// <summary>
        /// Returns a value that indicates a promotion level.
        /// </summary>
        /// <param name="type">WriteType to promotion.</param>
        /// <returns>Returns a promotion value.</returns>
        //public override int PromotionLevel(TypeExpression type) {
        //    if (this.fieldType != null)
        //        return this.fieldType.PromotionLevel(type);
        //    return -1;
        //}
        /// <summary>
        #endregion
        #region Promotion ANULADA
        /// Requires the implicit object to be a subtype of the type parameter
        /// </summary>
        /// <param name="type">WriteType to promotion.</param>
        /// <param name="methodAnalyzed">The method that is being analyzed when the operation is performed.</param>
        /// <param name="op">An optional operator to report error messages.</param>
        /// <param name="fileName">File name.</param>
        /// <param name="line">Line number.</param>
        /// <param name="column">Column number.</param>
        ///// <returns>The supertype; null if there has been some error.</returns>
        //public override TypeExpression Promotion(TypeExpression type, Enum op, MethodType methodAnalyzed, Location loc) {
        //    if (this.fieldType != null)
        //        return this.fieldType.Promotion(type, op, methodAnalyzed, loc);
        //    return null;
        //}
        #endregion

        #region Cast() ANULADA
        /// <summary>
        /// Tells if the type can be cast to the casttype
        /// </summary>
        /// <param name="castType">The expected type</param>
        /// <param name="methodAnalyzed">The method that is being analyzed when the operation is performed.</param>
        /// <param name="fileName">File name.</param>
        /// <param name="line">Line number.</param>
        /// <param name="column">Column number.</param>
        ///// <returns>The returned type expression</returns>
        //public override TypeExpression Cast(TypeExpression castType, MethodType methodAnalyzed, Location loc) {
        //    if (this.fieldType != null)
        //        return this.fieldType.Cast(castType, methodAnalyzed, loc);
        //    return null;
        //}
        #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));
            }
            return(false);
        }
Exemple #14
0
        // 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)
        {
            // * Infinite recursion detection
            Pair <TypeExpression, TypeExpression> pair = new Pair <TypeExpression, TypeExpression>(this, te);

            if (previouslyUnified.Contains(pair))
            {
                return(true);
            }
            previouslyUnified.Add(pair);

            // * First checks that all the expression are equivalent. Otherwise substitutions could be
            //   partially applied to type variables that should finally not be unified
            bool equivalent = true;

            foreach (TypeExpression type in this.typeSet)
            {
                if (!(equivalent = (bool)type.AcceptOperation(new EquivalentOperation(te), null)))
                {
                    break;
                }
            }
            if (!equivalent)
            {
                return(false);
            }
            // * Lets unify, incrementing type variables with union types
            foreach (TypeExpression type in this.typeSet)
            {
                // * Unification of union types is incremental
                te.Unify(type, SortOfUnification.Incremental, previouslyUnified);
            }
            // * Clears the type expression cache
            this.ValidTypeExpression = false;
            te.ValidTypeExpression   = false;
            return(true);
        }
Exemple #15
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);
        }
Exemple #16
0
        /// <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;
            UnionType union = type as UnionType;

            if (union != null)
            {
                foreach (TypeExpression t in union.typeSet)
                {
                    added = this.AddType(t) && added;
                }
                this.ValidTypeExpression = false;
                return(added);
            }
            TypeExpression existingType = typeSet.Find(type.Equals);

            if (existingType == null)
            {
                this.typeSet.Add(type);
                this.ValidTypeExpression = false;
                return(true);
            }
            return(false);
        }
Exemple #17
0
        // WriteType Promotion

        #region PromotionLevel()

        /// <summary>
        /// Returns a value thdat indicates a promotion level.
        /// </summary>
        /// <param name="type">WriteType to promotion.</param>
        /// <returns>Returns a promotion value.</returns>
        //public override int PromotionLevel(TypeExpression type) {
        //    int aux, less = -1;

        //    // * The same type
        //    if (this == type)
        //        return 0;
        //    // * Equivalent types
        //    if ((bool)this.AcceptOperation(new EquivalentOperation(type)))
        //        return 0;

        //    // * Field type and bounded type variable
        //    FieldType fieldType = TypeExpression.As<FieldType>(type);
        //    if (fieldType != null)
        //        return this.PromotionLevel(fieldType.FieldTypeExpression);

        //    // * WriteType variable
        //    TypeVariable typeVariable = type as TypeVariable;
        //    if (typeVariable != null) {
        //        if (typeVariable.Substitution != null)
        //            // * If the variable is bounded, the promotion is the one of its substitution
        //            return this.PromotionLevel(typeVariable.EquivalenceClass.Substitution);
        //        // * A free variable is complete promotion
        //        return 0;
        //    }

        //    // * Inheritance
        //    if (this.BaseClass == null)
        //        // * Object only promotes to object
        //        return -1;
        //    if ((bool)this.baseClass.AcceptOperation(new EquivalentOperation(type)))
        //        return 1;
        //    else {
        //        aux = this.baseClass.PromotionLevel(type);
        //        if (aux != -1)
        //            return aux + 1;
        //    }

        //    // * Interfaces
        //    if (this.interfaceList.Count != 0) {
        //        for (int i = 0; i < this.interfaceList.Count; i++) {
        //            if ((bool)this.interfaceList[i].AcceptOperation( new EquivalentOperation(type))) {
        //                if ((less > 1) || (less == -1))
        //                    less = 1;
        //            }
        //            else {
        //                aux = this.interfaceList[i].PromotionLevel(type);
        //                if (aux != -1) {
        //                    if ((less > (aux + 1)) || (less == -1))
        //                        less = aux + 1;
        //                }
        //            }
        //        }
        //    }
        //    if (less != -1)
        //        return less;

        //    // * Union type
        //    UnionType unionType = TypeExpression.As<UnionType>(type);
        //    if (unionType != null)
        //        return unionType.SuperType(this);

        //    // * No promotion
        //    return -1;
        //}

        #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)
        {
            // * Infinite recursion detection
            Pair <TypeExpression, TypeExpression> pair = new Pair <TypeExpression, TypeExpression>(this, te);

            if (previouslyUnified.Contains(pair))
            {
                return(true);
            }
            previouslyUnified.Add(pair);

            ClassType ct      = te as ClassType;
            bool      success = true;

            // * Class WriteType
            if (ct != null)
            {
                // * Inheritance is taken into account
                if ((int)ct.AcceptOperation(new PromotionLevelOperation(this), null) == -1)
                {
                    return(false);
                }
                // * Walk upward in the tree till find the correct class
                while (!(bool)ct.AcceptOperation(new EquivalentOperation(this), null))
                {
                    ct = ct.baseClass;
                }
                // * Now we unify the fields
                foreach (string key in this.Fields.Keys)
                {
                    FieldType thisField = (FieldType)this.Fields[key].Type,
                                teField = (FieldType)ct.Fields[key].Type;
                    if (thisField.FieldTypeExpression is ClassTypeProxy || teField.FieldTypeExpression is ClassTypeProxy)
                    {
                        success = thisField.FieldTypeExpression.FullName.Equals(teField.FieldTypeExpression.FullName);
                    }
                    else if (!(thisField.Unify(teField, unification, previouslyUnified)))
                    {
                        success = false;
                    }
                    if (!success)
                    {
                        break;
                    }
                }
                if (success && this.baseClass != null)
                {
                    // * The same with the base class
                    this.baseClass.Unify(ct.baseClass, unification, previouslyUnified);
                }
                // * If one of the classes is a concrete type, so it is the other
                if (success)
                {
                    this.ConcreteType = ct.ConcreteType = this.ConcreteType || ct.ConcreteType;
                }
            }
            // * WriteType variable
            else if (te is TypeVariable)
            {
                TypeVariable typeVariable = (TypeVariable)te;
                if (unification != SortOfUnification.Incremental)
                {
                    // * Incremental is commutative
                    success = typeVariable.Unify(this, unification, previouslyUnified);
                }
                // * Incremental unification (not commutative)
                else if (typeVariable.Substitution != null)
                {
                    // * Class(var) should unify to Var=Class(int)
                    success = this.Unify(typeVariable.Substitution, unification, previouslyUnified);
                }
                else
                {
                    success = false;
                }
            }
            // * Union WriteType
            else if (te is UnionType)
            {
                success = te.Unify(this, unification, previouslyUnified);
            }
            // * Class WriteType Proxy
            else if (te is ClassTypeProxy)
            {
                success = this.Unify(((ClassTypeProxy)te).RealType, unification, previouslyUnified);
            }
            else if (te is FieldType)
            {
                success = this.Unify(((FieldType)te).FieldTypeExpression, unification, previouslyUnified);
            }
            else
            {
                success = false;
            }
            // * Clears the type expression cache
            this.ValidTypeExpression = false;
            te.ValidTypeExpression   = false;
            return(success);
        }
        // Loop Detection

        // Helper Methods

        #region methodCall()

        /// <summary>
        /// This method does the type inference in a method call including unification.
        /// It requires that a) the method to be invoked has been previously analyzed with this visitor
        /// b) The formalMethod parameter is the result of the overload resolution
        /// </summary>
        /// <param name="actualImplicitObject">The actual implicit object</param>
        /// <param name="formalMethod">The formal method to be called</param>
        /// <param name="args">The ordered types of the actual parameters</param>
        /// <param name="methodAnalyzed">The method that is being analyzed when the operation is performed.</param>
        /// <param name="activeSortOfUnification">The active sort of unification used (Equivalent is the default
        /// one and Incremental is used in the SSA bodies of the while, for and do statements)</param>
        /// <param name="fileName">File name.</param>
        /// <param name="line">Line number.</param>
        /// <param name="column">Column number.</param>
        /// <returns>The type expression of the returned value</returns>
        public static TypeExpression methodCall(TypeExpression actualImplicitObject, MethodType formalMethod, TypeExpression[] args,
                                                MethodType methodAnalyzed, SortOfUnification activeSortOfUnification, Location location)
        {
            UserType   userType     = formalMethod.MemberInfo.Class;
            MethodType actualMethod = null;
            // * We must create a new type with type variables for the object's attributes (the formal implicit object)
            IDictionary <TypeVariable, TypeVariable> typeVariableMappings = new Dictionary <TypeVariable, TypeVariable>();

            // * If the method is an instance one and the actual object is not this, we create a new implicit object to unify
            if (!formalMethod.MemberInfo.hasModifier(Modifier.Static) && actualImplicitObject != null && actualImplicitObject != methodAnalyzed.memberInfo.Class)
            {
                // * Unifies the implicit objects (actual and formal)
                UserType formalImplicitObject = (UserType)userType.CloneType(typeVariableMappings);
                if (!actualImplicitObject.Unify(formalImplicitObject, SortOfUnification.Equivalent, new List <Pair <TypeExpression, TypeExpression> >()))
                {
                    // * If the formal implicit object already has substitution (fields declararion with assignments), we override it with a union type
                    formalImplicitObject.Unify(actualImplicitObject, SortOfUnification.Override, new List <Pair <TypeExpression, TypeExpression> >());
                }
                actualImplicitObject.ValidTypeExpression = false;
            }

            // * If "this" is the actual implicit object, the return type is the original return type of the method
            TypeExpression originalReturnType = formalMethod.Return;

            if (formalMethod.HasTypeVariables() || formalMethod.Constraints.Count > 0)
            {
                // * We must also generate a method with fresh variables (formal method)
                //   when it has parameters with type variables or constraints
                formalMethod = formalMethod.CloneMethodType(typeVariableMappings);
            }

            // * If the method has type variables...
            if (formalMethod.HasTypeVariables())
            {
                // * We create the actual method:
                //   1.- The actual return type
                TypeVariable actualReturnType = TypeVariable.NewTypeVariable;
                //   2.- The actual method
                actualMethod = new MethodType(actualReturnType);
                //   3.- The actual parameters
                foreach (TypeExpression arg in args)
                {
                    actualMethod.AddParameter(arg);
                }

                // * Unifies both methods
                if (!actualMethod.Unify(formalMethod, SortOfUnification.Equivalent, new List <Pair <TypeExpression, TypeExpression> >()))
                {
                    ErrorManager.Instance.NotifyError(new UnificationError(actualMethod.FullName, location));
                    return(null);
                }
            }
            // * Otherwise, arguments promotion must be checked
            else
            {
                if (args.Length != formalMethod.ParameterListCount)
                {
                    ErrorManager.Instance.NotifyError(new ArgumentNumberError(formalMethod.FullName, args.Length, location));
                    return(null);
                }
                for (int i = 0; i < args.Length; i++)
                {
                    if (args[i].AcceptOperation(PromotionOperation.Create(formalMethod.paramList[i], methodAnalyzed, location), null) == null)
                    {
                        return(null);
                    }
                }
            }

            // * Method constraints satisfaction
            if (formalMethod.Constraints.Count > 0)
            {
                formalMethod.Constraints.Check(methodAnalyzed, actualImplicitObject, true, activeSortOfUnification, location);
            }

            // * The returned type is the the actual method if there has been a unification and
            //   in case the method is a instance method, a concrete object has been used (not this) or
            //   a different implicit object (the this reference is changed in the SSA algorithm)
            if (actualMethod != null && (formalMethod.MemberInfo.hasModifier(Modifier.Static) ||
                                         ClassType.IsConcreteType(actualImplicitObject) != null ||
                                         actualImplicitObject != formalMethod.MemberInfo.Class))
            {
                TypeVariable returnType = (TypeVariable)actualMethod.Return;
                if (returnType.Substitution != null)
                {
                    return(returnType.EquivalenceClass.Substitution);
                }
                return(returnType);
            }
            // * The original returned type if there has been no unification or the implicit object is "this"
            return(originalReturnType);
        }
 /// <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)
 {
     return(false);
 }
        /// <summary>
        /// To add a new type to the class equivalence.
        /// </summary>
        /// <param name="te">The type to be added</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 substitution has been correctly applied</returns>
        public bool add(TypeExpression te, SortOfUnification unification, IList <Pair <TypeExpression, TypeExpression> > previouslyUnified)
        {
            TypeVariable tv = te as TypeVariable;

            if (tv != null)   // * Another type variable
            // * Tries to add its substitution
            {
                if (tv.Substitution != null)                                                         // * If it has a substitution
                {
                    if (!this.add(tv.EquivalenceClass.Substitution, unification, previouslyUnified)) // * We try to add it to ourselves
                    {
                        return(false);                                                               // * Both susbstitutions are not the same
                    }
                }
                // * If no error, we add it to the equivalence class
                this.typeVariables[tv.Variable] = tv;
                if (tv.EquivalenceClass != null)    // * The parameter already has a equivalence class
                {
                    foreach (KeyValuePair <int, TypeVariable> pair in tv.EquivalenceClass.TypeVariables)
                    {
                        if (!this.typeVariables.ContainsKey(pair.Key))
                        {
                            // * We recursively add all the element of the equivalence class
                            this.typeVariables[pair.Key] = pair.Value;
                            this.add(pair.Value, unification, previouslyUnified);
                        }
                    }
                }
                // * Finally, we update the equivalence class of tv
                tv.EquivalenceClass = this;
                return(true);
            }
            // * te is not a type variable
            if (this.substitution != null)
            {
                // * A substitution already exists
                if (unification == SortOfUnification.Equivalent)
                {
                    // * They must be equivalent
                    if (!(bool)this.substitution.AcceptOperation(new EquivalentOperation(te), null))
                    {
                        return(false);
                    }
                    if (te.HasTypeVariables())
                    {
                        // var1=Array(int) must be unified to Array(var1)
                        return(te.Unify(this.substitution, unification, previouslyUnified));
                    }
                    return(true);
                }
                if (unification == SortOfUnification.Incremental)
                {
                    // * The incremental behaviour implies a union of all the types
                    this.substitution = UnionType.collect(this.substitution, te);
                    return(true);
                }
                // * Override unification (the susbstitution is overridden)
                this.substitution = te;
                return(true);
            }
            // * We set the type as a susbstitution
            substitution = te;
            return(true);
        }
Exemple #21
0
        /// <summary>
        ///// Check if the type can make an assignment 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="unification">Indicates if the kind of unification (equivalent, incremental or override).</param>
        ///// <param name="actualImplicitObject">Only suitable when the assignment is executed as a constraint of a method call. In that case,
        ///// this parameter represents the actual object used to pass the message; null otherwise.</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 Assignment(TypeExpression operand, AssignmentOperator op, MethodType methodAnalyzed, SortOfUnification unification,
        //            TypeExpression actualImplicitObject, Location location) {
        //    if (op == AssignmentOperator.Assign)
        //        return operand;
        //    else
        //        ErrorManager.Instance.NotifyError(new AssignmentError(operand.FullName, this.FullName, location));
        //    return null;
        //}
        #endregion

        #region Arithmetic() ANULADA

        /*
         * /// <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 (op.Equals(ArithmeticOperator.Plus) && operand.Equivalent(StringType.Instance))
         *      return StringType.Instance;
         *  if (showErrorMessage)
         *      ErrorManager.Instance.NotifyError(new TypePromotionError(operand.FullName, this.FullName, op.ToString(), loc));
         *  return null;
         * } */
        #endregion

        // WriteType Promotion

        #region PromotionLevel() ANULADA

        /// <summary>
        /// Returns a value that indicates a promotion level.
        /// </summary>
        /// <param name="type">WriteType to promotion.</param>
        /// <returns>Returns a promotion value.</returns>
        //public override int PromotionLevel(TypeExpression type) {
        //    // * Built-in types: no promotion, except string
        //    if (type is BoolType || type is CharType || type is DoubleType || type is IntType || type is VoidType)
        //        return -1;
        //    // * BCL Value Types (structs): No promotion
        //    BCLClassType bclClass = TypeExpression.As<BCLClassType>(type);
        //    if (bclClass != null) {
        //        if (bclClass.TypeInfo.IsValueType)
        //            return -1;
        //        // * Correct promotion to classes that are not value types
        //        return 0;
        //    }
        //    // * WriteType variable
        //    TypeVariable typeVariable = type as TypeVariable;
        //    if (typeVariable != null) {
        //        if (typeVariable.Substitution != null)
        //            // * If the variable is bounded, the promotion is the one of its substitution
        //            return this.PromotionLevel(typeVariable.EquivalenceClass.Substitution);
        //        // * A free variable is complete promotion
        //        return 0;
        //    }
        //    // * Union type
        //    UnionType unionType = TypeExpression.As<UnionType>(type);
        //    if (unionType != null)
        //        return unionType.SuperType(this);
        //    // * Field type and bounded type variable
        //    FieldType fieldType = TypeExpression.As<FieldType>(type);
        //    if (fieldType != null)
        //        return this.PromotionLevel(fieldType.FieldTypeExpression);
        //    // * Correct Promotion
        //    return 0;
        //}

        #endregion

        // WriteType Unification

        #region Unify
        /// <summary>
        /// This method unifies two type expressions (this and te)
        /// </summary>
        /// <param name="unification">Indicates if the kind of unification (equivalent, incremental or override).</param>
        /// <param name="te">The expression to be unfied with this</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)
        {
            throw new NotImplementedException("NullType.Unify() Not implemented");
        }
 /// <summary>
 /// Constructor of Intersection
 /// </summary>
 public IntersectionMemberType(TypeExpression te) : base(te)
 {
 }
 /// <summary>
 /// Used to not repeat methods in overload
 /// </summary>
 /// <param name="typeExpression">The other type expression</param>
 /// <returns>If both represent the same type</returns>
 public virtual bool EqualsForOverload(TypeExpression typeExpression)
 {
     return((bool)this.AcceptOperation(new EqualsForOverloadOperation(typeExpression), null));
 }
Exemple #24
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);
 }
Exemple #25
0
        // WriteType Promotion

        #region PromotionLevel() ANULADA
        //public virtual int PromotionLevel(TypeExpression type) {
        //    return -1;
        //}
        #endregion

        #region Promotion() ANULADA
        /// <summary>
        /// Requires the implicit object to be a subtype of the type parameter
        /// </summary>
        /// <param name="type">WriteType to promotion.</param>
        /// <param name="methodAnalyzed">The method that is being analyzed when the operation is performed.</param>
        /// <param name="op">An optional operator to report error messages.</param>
        /// <param name="fileName">File name.</param>
        /// <param name="line">Line number.</param>
        /// <param name="column">Column number.</param>
        /// <returns>The supertype; null if there has been some error.</returns>
        //public virtual TypeExpression Promotion(TypeExpression type, MethodType methodAnalyzed, Location location) {
        //    if ((int) this.AcceptOperation(new PromotionLevelOperation(type)) == -1) {
        //        ErrorManager.Instance.NotifyError(new TypePromotionError(this.FullName, type.FullName, location));
        //        return null;
        //    }
        //    return type;
        //}
        //public virtual TypeExpression Promotion(TypeExpression type, Enum op, MethodType methodAnalyzed, Location location) {
        //    if ((int)this.AcceptOperation( new PromotionLevelOperation(type)) == -1) {
        //        ErrorManager.Instance.NotifyError(new TypePromotionError(this.FullName, type.FullName, op.ToString(), location));
        //        return null;
        //    }
        //    return type;
        //}
        #endregion

        #region Cast() ANULADA
        /// <summary>
        /// Tells if the type can be cast to the casttype
        /// </summary>
        /// <param name="castType">The expected type</param>
        /// <param name="methodAnalyzed">The method that is being analyzed when the operation is performed.</param>
        /// <param name="fileName">File name.</param>
        /// <param name="line">Line number.</param>
        /// <param name="column">Column number.</param>
        /// <returns>The returned type expression</returns>
        //public virtual TypeExpression Cast(TypeExpression castType, MethodType methodAnalyzed, Location loc) {
        //    if (castType == null)
        //        return null;
        //    if (((int)castType.AcceptOperation(new PromotionLevelOperation(this)) != -1) || ((int)this.AcceptOperation(new PromotionLevelOperation(castType)) != -1))
        //        return castType;
        //    ErrorManager.Instance.NotifyError(new TypeCastError(this.FullName, castType.FullName, loc));
        //    return null;
        //}
        #endregion

        #region EqualsForOverload() ANULADA
        /// <summary>
        /// Used to not repeat methods in overload
        /// </summary>
        /// <param name="typeExpression">The other type expression</param>
        /// <returns>If both represent the same type</returns>
        //public virtual bool EqualsForOverload(object typeExpression) {
        //    // * By default, we use the equals comparison
        //    return this.Equals(typeExpression);
        //}
        #endregion

        // WriteType Unification

        #region Unify()
        /// <summary>
        /// Tries to unify the type expression of this and the parameter
        /// </summary>
        /// <param name="te">The type expression to be unified together 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 both type expressionas could be unfied</returns>
        public abstract bool Unify(TypeExpression te, SortOfUnification unification, IList <Pair <TypeExpression, TypeExpression> > previouslyUnified);
 /// <summary>
 /// Adds a new parameter type.
 /// </summary>
 /// <param name="paramType">Parameter type.</param>
 public void AddParameter(TypeExpression paramType)
 {
     this.paramList.Add(paramType);
 }
 public IntersectionType(TypeExpression te)
 {
     this.AddType(te);
     this.BuildFullName();
 }
        // 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);
        }
        // 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)
        {
            return(this.RealType.Unify(te, unification, previouslyUnified));
        }
Exemple #30
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);
        }