// 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); }
// 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); }