예제 #1
0
        /// <summary>
        /// Finds and adds the list of constructor to a BCL type
        /// </summary>
        /// <param name="fileName">File name.</param>
        /// <param name="line">Line number.</param>
        /// <param name="column">Column number.</param>
        /// <returns>WriteType obtained</returns>
        public TypeExpression FindConstructor(Location location)
        {
            ConstructorInfo[] constructors = userType.TypeInfo.GetConstructors();
            AccessModifier    accessModifierInfo;
            MethodType        mt;

            foreach (ConstructorInfo constructor in constructors)
            {
                mt = new MethodType((UserType)userType); // The constructor returns its own class
                ParameterInfo[] parameters = constructor.GetParameters();
                for (int j = 0; j < parameters.GetLength(0); j++)
                {
                    mt.AddParameter(TypeTable.Instance.GetType(parameters[j].ParameterType.FullName, location));
                }

                List <Modifier> mods = getMethodModifierList(constructor);

                accessModifierInfo       = new AccessModifier(mods, constructor.Name, mt, false);
                mt.MemberInfo            = accessModifierInfo;
                accessModifierInfo.Class = (UserType)userType;

                if (userType.Constructors != null)
                {
                    if (!(userType.Constructors.Type is IntersectionType)) // * It is not an intersection
                    // * An intersection type must be created
                    {
                        userType.Members[userType.Name].Type = new IntersectionMemberType(userType.Members[userType.Name].Type);
                    }
                    // * The type is added
                    ((IntersectionType)userType.Members[userType.Name].Type).AddType(mt);
                }
                else
                {
                    userType.AddMember(userType.Name, accessModifierInfo);
                }
                accessModifierInfo.Type.BuildTypeExpressionString(TypeExpression.MAX_DEPTH_LEVEL_TYPE_EXPRESSION);
            }
            if (userType.Members.ContainsKey(userType.Name))
            {
                return(userType.Members[userType.Name].Type);
            }
            return(null);
        }
예제 #2
0
        /// <summary>
        /// Creates a MethodType using the method information.
        /// </summary>
        /// <param name="methods">Methods information.</param>
        /// <param name="fileName">File name.</param>
        /// <param name="line">Line number.</param>
        /// <param name="column">Column number.</param>
        private void createMethods(MethodInfo[] methods, Location location)
        {
            AccessModifier accessModifierInfo;
            MethodType     mt;

            foreach (MethodInfo method in methods)
            {
                mt = new MethodType(TypeTable.Instance.GetType(method.ReturnType.FullName, location));
                ParameterInfo[] parameters = method.GetParameters();
                for (int j = 0; j < parameters.GetLength(0); j++)
                {
                    if (parameters[j].ParameterType.FullName != null)
                    {
                        mt.AddParameter(TypeTable.Instance.GetType(parameters[j].ParameterType.FullName, location));
                    }
                }

                List <Modifier> mods = getMethodModifierList(method);

                accessModifierInfo       = new AccessModifier(mods, method.Name, mt, false);
                mt.MemberInfo            = accessModifierInfo;
                accessModifierInfo.Class = (UserType)userType;

                if (userType.Members.ContainsKey(method.Name))
                {
                    if (!(userType.Members[method.Name].Type is IntersectionType)) // * It is not an intersection
                    // * An intersection type must be created
                    {
                        userType.Members[method.Name].Type = new IntersectionMemberType(userType.Members[method.Name].Type);
                    }
                    // * The type is added
                    ((IntersectionType)userType.Members[method.Name].Type).AddType(mt);
                }
                else
                {
                    userType.AddMember(method.Name, accessModifierInfo);
                }
                accessModifierInfo.Type.BuildTypeExpressionString(TypeExpression.MAX_DEPTH_LEVEL_TYPE_EXPRESSION);
            }
        }
예제 #3
0
        // 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);
        }