/// <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> public override object Exec(TypeVariable tv) { // * If the variable to be cloned already has a map, we return the latter if (this.typeVariableMappings.ContainsKey(tv)) { return(this.typeVariableMappings[tv]); } TypeVariable newOne = TypeVariable.NewTypeVariable; newOne.IsDynamic = tv.IsDynamic; // * Sets the mapping between the old and new one in the typeVariableMappings parameter this.typeVariableMappings[tv] = newOne; // * Add both equivalence classes to the equivalenceClasses parameter if (tv.EquivalenceClass != null && !this.equivalenceClasses.Contains(tv.EquivalenceClass)) { this.equivalenceClasses.Add(tv.EquivalenceClass); } // * Assigns a clone of the substitution when it previously exists if (tv.Substitution != null) { TypeExpression clonedSubstitution = (TypeExpression)tv.Substitution.Exec(this); newOne.addToMyEquivalenceClass(clonedSubstitution, SortOfUnification.Equivalent, new List <Pair <TypeExpression, TypeExpression> >()); } else if (tv.EquivalenceClass != null) { newOne.EquivalenceClass = tv.EquivalenceClass; } newOne.ValidTypeExpression = false; // * Returns the new type variable return(newOne); }
/// <summary> /// It performs a an assigment operation with a TypeVariable as left operand. /// </summary> /// <param name="leftOperand">leftOperand is Typevariable in the left par of the assignment</param> /// <returns>The result of the assignment if possible null and error if not.</returns> public override object Exec(TypeVariable leftOperand, object arg) { // * Bounded variable? if (leftOperand.Substitution != null && this.unification == SortOfUnification.Equivalent) { // * Check promotion to its substitution return(rightOperand.AcceptOperation(PromotionOperation.Create(leftOperand, this.op, this.methodAnalyzed, this.location), arg)); } // * If the variable its not bounded, we add the parameter to the equivalence list if (leftOperand.addToMyEquivalenceClass(rightOperand, this.unification, new List <Pair <TypeExpression, TypeExpression> >())) { return(leftOperand); } // * If it has not been possible, error ErrorManager.Instance.NotifyError(new OperationNotAllowedError(this.op.ToString(), leftOperand.FullName, rightOperand.FullName, this.location)); return(null); }