Exemplo n.º 1
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);
        }