Exemple #1
0
        // SSA

        #region Clone()
        /// <summary>
        /// Clones a type to be used in SSA. It must taken into account that:
        /// - In case it has no type variables, no clone is performed
        /// - WriteType variables, equivalence classes and substitutions are cloned
        /// </summary>
        /// <param name="clonedTypeVariables">WriteType variables that have been cloned.</param>
        /// <param name="equivalenceClasses">Equivalence classes of the type cloned variables. These
        /// equivalence classes need to be updated with the new cloned type variables.</param>
        /// <param name="methodAnalyzed">The method that is being analyzed when the operation is performed.</param>
        /// <returns>The cloned type</returns>
        internal override TypeExpression Clone(IDictionary <int, TypeVariable> clonedTypeVariables, IList <EquivalenceClass> equivalenceClasses, MethodType methodAnalyzed)
        {
            if (clonedTypeVariables.ContainsKey(this.variable))
            {
                // * Already cloned
                return(clonedTypeVariables[this.variable]);
            }
            if (this.Substitution != null)
            {
                // * Lets clone it
                TypeVariable newTypeVariable = (TypeVariable)this.MemberwiseClone();
                newTypeVariable.variable = TypeVariable.NewTypeVariable.Variable;
                // * We add it to the list
                clonedTypeVariables[this.variable] = newTypeVariable;
                // * We also clone all the type variables of its class equivalence
                if (newTypeVariable.equivalenceClass != null)
                {
                    newTypeVariable.equivalenceClass.CloneTypeVariables(clonedTypeVariables, equivalenceClasses, methodAnalyzed);
                }
                newTypeVariable.BuildFullName();
                newTypeVariable.BuildTypeExpressionString(2);
                return(newTypeVariable);
            }
            if (methodAnalyzed != null)
            {
                // * A clone constraint is added to the method analyzed
                CloneConstraint constraint = new CloneConstraint(this);
                methodAnalyzed.AddConstraint(constraint);
                // * We add it to the list
                clonedTypeVariables[this.variable] = constraint.ReturnType;
                // * We also clone all the type variables of its class equivalence
                if (this.equivalenceClass != null)
                {
                    this.equivalenceClass.CloneTypeVariables(clonedTypeVariables, equivalenceClasses, methodAnalyzed);
                }
                return(constraint.ReturnType);
            }
            return(null);
        }
Exemple #2
0
        public override Object Visit(MethodDefinition node, Object obj)
        {
            typeVariableMappings         = new Dictionary <TypeVariable, TypeVariable>();
            typeExpresionVariableMapping = new Dictionary <TypeExpression, TypeExpression>();
            var        previouslyUnified  = new List <Pair <TypeExpression, TypeExpression> >();
            MethodType originalMethodType = (MethodType)node.TypeExpr;

            TypeExpression[] args                 = (TypeExpression[])obj;
            TypeExpression[] clonedArgs           = new TypeExpression[args.Count()];
            List <Parameter> clonedParametersInfo = new List <Parameter>();

            for (int i = 0; i < node.ParametersInfo.Count; i++)
            {
                Parameter      originalParameter = node.ParametersInfo[i];
                TypeExpression originalParamType = originalMethodType.GetParameter(i);
                if (originalParamType is TypeVariable)
                {
                    TypeVariable clonedParamType = (TypeVariable)originalParamType.CloneType(typeVariableMappings);
                    if (clonedParamType.EquivalenceClass != null)
                    {
                        clonedParamType.EquivalenceClass.add(args[i], SortOfUnification.Override, previouslyUnified);
                        typeExpresionVariableMapping.Add(originalParamType, clonedParamType);
                        originalParamType = clonedParamType;
                    }
                    else
                    {
                        typeExpresionVariableMapping.Add(originalParamType, args[i]);
                        originalParamType = args[i];
                    }
                }

                originalParamType.ValidTypeExpression = false;
                clonedArgs[i] = originalParamType.Simplify();
                var parameter = new Parameter()
                {
                    Identifier = originalParameter.Identifier, Column = originalParameter.Column, Line = originalParameter.Line, ParamType = clonedArgs[i].typeExpression
                };
                if (parameter.ParamType == null || !originalParameter.ILName.Equals(parameter.ILName))
                {
                    var rebuildParamType = clonedArgs[i].ToString();
                    parameter.ParamType = clonedArgs[i].typeExpression;
                }

                clonedParametersInfo.Add(parameter);
            }

            foreach (var constraint in originalMethodType.Constraints.Constraints)
            {
                if (constraint is CloneConstraint)
                {
                    CloneConstraint cc = constraint as CloneConstraint;
                    if (typeExpresionVariableMapping.ContainsKey(cc.FirstOperand))
                    {
                        typeExpresionVariableMapping.Add(cc.ReturnType, typeExpresionVariableMapping[cc.FirstOperand]);
                    }
                }
            }
            MethodType clonedMethodType = new MethodType(originalMethodType.Return.CloneType(typeVariableMappings, typeExpresionVariableMapping));

            currentMethodType = clonedMethodType;

            SingleIdentifierExpression clonedSingleIdentifierExpression = new SingleIdentifierExpression(node.IdentifierExp.Identifier, node.IdentifierExp.Location);

            Block            clonedBlock            = (Block)node.Body.Accept(this, null);
            MethodDefinition clonedMethodDefinition = null;

            if (node is ConstructorDefinition)
            {
                clonedMethodDefinition = new ConstructorDefinition(clonedSingleIdentifierExpression, node.ModifiersInfo, clonedParametersInfo, null, clonedBlock, node.Location);
            }
            else
            {
                clonedMethodDefinition = new MethodDefinition(clonedSingleIdentifierExpression, clonedBlock, clonedMethodType.Return.typeExpression, clonedParametersInfo, node.ModifiersInfo, node.Location);
            }
            clonedMethodDefinition.FullName            = node.FullName;
            clonedMethodType.MemberInfo                = new AccessModifier(originalMethodType.MemberInfo.Modifiers, clonedSingleIdentifierExpression.Identifier, clonedMethodType, false);
            clonedMethodType.MemberInfo.Class          = originalMethodType.MemberInfo.Class;
            clonedMethodType.MemberInfo.TypeDefinition = originalMethodType.MemberInfo.TypeDefinition;
            for (int i = 0; i < originalMethodType.ParameterListCount; i++)
            {
                clonedMethodType.AddParameter(clonedArgs[i]);
            }
            clonedMethodType.ASTNode        = clonedMethodDefinition;
            clonedMethodDefinition.TypeExpr = clonedMethodType;


            var previousShowMessages = ErrorManager.Instance.ShowMessages;

            ErrorManager.Instance.UnNotifiedErrors = false;
            ErrorManager.Instance.ShowMessages     = false;
            clonedMethodDefinition.Accept(this.visitorSpecializer.visitorTypeInference, null);
            ErrorManager.Instance.ShowMessages = previousShowMessages;
            if (ErrorManager.Instance.UnNotifiedErrors)
            {
                ErrorManager.Instance.UnNotifiedErrors = false;
                return(null);
            }

            TypeDefinition originalTypeDefinition = clonedMethodType.MemberInfo.TypeDefinition;

            originalTypeDefinition.AddMethod(clonedMethodDefinition);

            UserType               originalClass          = clonedMethodType.MemberInfo.Class;
            AccessModifier         am                     = originalClass.Members[clonedMethodDefinition.Identifier];
            IntersectionMemberType intersectionMemberType = am.Type as IntersectionMemberType;

            if (intersectionMemberType != null)
            {
                intersectionMemberType.TypeSet.Add(clonedMethodType);
            }
            else
            {
                am = clonedMethodType.MemberInfo;
                IntersectionMemberType intersection = new IntersectionMemberType();
                intersection.TypeSet.Add(originalMethodType);
                intersection.TypeSet.Add(clonedMethodType);
                am.Type = intersection;
                originalClass.Members[clonedMethodDefinition.Identifier] = am;
            }

            clonedMethodDefinition.IdentifierExp.ExpressionType = clonedMethodDefinition.TypeExpr;
            return(clonedMethodDefinition);
        }