Ejemplo n.º 1
0
        public override object Exec(TypeExpression operand1, object arg)
        {
            if (this.operand2 == operand1)
            {
                return(true);
            }
            TypeVariable typeVariable = this.operand2 as TypeVariable;

            if (typeVariable != null)
            {
                return(typeVariable.AcceptOperation(new EquivalentOperation(operand1), arg));
            }
            FieldType fieldType = this.operand2 as FieldType;

            if (fieldType != null)
            {
                return(fieldType.AcceptOperation(this, arg));
            }
            UnionType unionType = this.operand2 as UnionType;

            if (unionType != null)
            {
                return(this.operand2.FullName.Contains(operand1.FullName));
            }
            return(operand1.FullName.Equals(this.operand2.FullName));
        }
        public override object Exec(TypeExpression operand1, object arg)
        {
            if (this.operand2 == operand1)
            {
                return(true);
            }
            TypeVariable typeVariable = this.operand2 as TypeVariable;

            if (typeVariable != null)
            {
                return(typeVariable.AcceptOperation(new EquivalentOperation(operand1), arg));
            }

            return(operand1.FullName.Equals(this.operand2.FullName));
        }
        public override object Exec(MethodType operand1, object arg)
        {
            if (operand1 == this.operand2)
            {
                return(true);
            }

            TypeVariable typeVariable = this.operand2 as TypeVariable;

            if (typeVariable != null)
            {
                return(typeVariable.AcceptOperation(new EquivalentOperation(operand1), arg));
            }

            MethodType method = this.operand2 as MethodType;

            // * It must be a method
            if (method == null)
            {
                return(false);
            }
            // * Same name
            if (!operand1.MemberInfo.MemberIdentifier.Equals(method.MemberInfo.MemberIdentifier))
            {
                return(false);
            }
            // * Same class
            if (!(bool)operand1.MemberInfo.Class.AcceptOperation(new EquivalentOperation(method.MemberInfo.Class), null))
            {
                return(false);
            }
            // * Same signature
            if (operand1.ParameterListCount != method.ParameterListCount)
            {
                return(false);
            }
            for (int i = 0; i < operand1.ParameterListCount; i++)
            {
                if (!(bool)operand1.GetParameter(i).AcceptOperation(new EquivalentOperation(method.GetParameter(i)), null))
                {
                    return(false);
                }
            }
            return(true);
        }
        /// <summary>
        /// Performs an assigment operation between a FieldType type and the typeExpression stored in this.rightOperand.
        /// The result of the operation is the resulting operation of doing PromotionOperation the operation.
        /// </summary>
        /// <param name="leftOperand">A FieldType, the left operand of the assignment/param>
        /// <returns> The result of the operation is the resulting operation of doing The Assignment operation.
        ///</returns>
        public override object Exec(FieldType leftOperand, object arg)
        {
            // * 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 (leftOperand.HasTypeVariables() && this.methodAnalyzed != null &&
                ClassType.IsConcreteType(this.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)this.methodAnalyzed.MemberInfo.Class;
                while (!(found = (leftOperand.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 = leftOperand;
                    ClassType thisType  = TypeExpression.As <ClassType>(this.actualImplicitObject);
                    if (thisType == null)
                    {
                        FieldType field = TypeExpression.As <FieldType>(this.actualImplicitObject);
                        if (field != null)
                        {
                            thisType = TypeExpression.As <ClassType>(field.FieldTypeExpression);
                        }
                    }

                    if (thisType != null)
                    {
                        while (thisType != null && !thisType.Fields.ContainsKey(leftOperand.MemberInfo.MemberIdentifier))
                        {
                            thisType = thisType.BaseClass;
                        }
                        if (thisType != null)
                        {
                            fieldType = (FieldType)thisType.Fields[leftOperand.MemberInfo.MemberIdentifier].Type;
                        }
                    }

                    this.methodAnalyzed.AddConstraint(new FieldTypeAssignmentConstraint(fieldType, this.rightOperand,
                                                                                        this.unification));
                    this.methodAnalyzed.ValidTypeExpression = false;
                    if (leftOperand.FieldTypeExpression is TypeVariable && rightOperand is ArrayType)
                    {
                        TypeVariable typeVariable = (TypeVariable)leftOperand.FieldTypeExpression;
                        typeVariable.AcceptOperation(new AssignmentOperation(rightOperand, this.op, null, SortOfUnification.Override, null, this.location), arg);
                    }
                    else if (leftOperand.FieldTypeExpression is TypeVariable && TypeExpression.As <ClassType>(rightOperand) != null && ((TypeVariable)leftOperand.FieldTypeExpression).IsDynamic)
                    {
                        TypeVariable typeVariable = (TypeVariable)leftOperand.FieldTypeExpression;
                        typeVariable.AcceptOperation(new AssignmentOperation(rightOperand, this.op, null, SortOfUnification.Override, null, this.location), arg);
                    }
                    else if (leftOperand.FieldTypeExpression is TypeVariable && rightOperand is TypeVariable && ((TypeVariable)rightOperand).Substitution == null && ((TypeVariable)rightOperand).IsDynamic)
                    {
                        TypeVariable typeVariable = (TypeVariable)leftOperand.FieldTypeExpression;
                        typeVariable.AcceptOperation(new AssignmentOperation(rightOperand, this.op, null, SortOfUnification.Override, null, this.location), arg);
                    }
                    return(leftOperand.FieldTypeExpression);
                }
                if (leftOperand.FieldTypeExpression is TypeVariable)
                {
                    TypeVariable typeVariable = (TypeVariable)leftOperand.FieldTypeExpression;
                    if (typeVariable.Substitution != null)
                    {
                        return
                            (leftOperand.FieldTypeExpression.AcceptOperation(
                                 new AssignmentOperation(this.rightOperand, this.op, null,
                                                         SortOfUnification.Incremental, this.actualImplicitObject,
                                                         this.location), arg));
                    }
                }
            }

            if (leftOperand.FieldTypeExpression != null)
            {
                return
                    (leftOperand.FieldTypeExpression.AcceptOperation(
                         new AssignmentOperation(this.rightOperand, this.op, null, this.unification,
                                                 this.actualImplicitObject, this.location), arg));
            }

            return(null);
        }