private Object builtMethod(MethodDeclaration node)
        {
            bool interfaceMember = false;

            if (!((node is MethodDefinition) || (node is ConstructorDefinition)))
            {
                interfaceMember = true;
            }

            TypeExpression ret = this.searchType(node.ReturnTypeInfo, node.Location.Line, node.Location.Column);

            if (ret == null)
            {
                ErrorManager.Instance.NotifyError(new UnknownTypeError(node.ReturnTypeInfo, node.Location));
                ret = this.searchType("void", node.Location.Line, node.Location.Column);
            }
            MethodType type = new MethodType(ret);

            type.ASTNode = node; // * Binds the MethodType with the appropriate AST node
            for (int i = 0; i < node.ParametersInfo.Count; i++)
            {
                TypeExpression paramType = this.searchType(node.ParametersInfo[i].ParamType, node.ParametersInfo[i].Line, node.ParametersInfo[i].Column);
                if (paramType == null)
                {
                    ErrorManager.Instance.NotifyError(new UnknownTypeError(node.ParametersInfo[i].ParamType, new Location(node.Location.FileName, node.ParametersInfo[i].Line, node.ParametersInfo[i].Column)));
                }
                type.AddParameter(paramType);
            }
            AccessModifier accessModifierInfo = new AccessModifier(node.ModifiersInfo, node.Identifier, type, interfaceMember);

            type.MemberInfo = accessModifierInfo;
            node.TypeExpr   = type;
            return(accessModifierInfo);
        }
Beispiel #2
0
        public void testUnify3Wrong()
        {
            // * "Array(Var(alpha))->Var(alpha)"
            TypeExpression alpha = TypeVariable.NewTypeVariable;
            MethodType     type1 = new MethodType(alpha);

            type1.AddParameter(new ArrayType(alpha));

            // * "Array(Array(int))->double"
            MethodType type2 = new MethodType(DoubleType.Instance);

            type2.AddParameter(new ArrayType(new ArrayType(IntType.Instance)));

            Unify(type1, type2);
        }
Beispiel #3
0
        public void testUnify6OK()
        {
            // * "( Var(alpha) -> Array( int )"
            TypeExpression alpha = TypeVariable.NewTypeVariable;
            MethodType     type1 = new MethodType(new ArrayType(IntType.Instance));

            type1.AddParameter(alpha);

            // * "( Var(beta) -> Array( Var(beta) )"
            TypeExpression beta  = TypeVariable.NewTypeVariable;
            MethodType     type2 = new MethodType(new ArrayType(beta));

            type2.AddParameter(beta);

            Unify(type1, type2);
        }
Beispiel #4
0
        public void testUnify4Wrong()
        {
            // * "Array(Var(alpha))->Var(alpha)"
            TypeExpression alpha = TypeVariable.NewTypeVariable;
            MethodType     type1 = new MethodType(alpha);

            type1.AddParameter(new ArrayType(alpha));

            // * "(Array(Array(int))->Var(beta)) -> Var(gamma)"
            TypeExpression beta  = TypeVariable.NewTypeVariable;
            TypeExpression gamma = TypeVariable.NewTypeVariable;
            MethodType     type2 = new MethodType(gamma);
            MethodType     type3 = new MethodType(beta);

            type3.AddParameter(new ArrayType(new ArrayType(IntType.Instance)));
            type2.AddParameter(type3);

            Unify(type1, type2);
        }
Beispiel #5
0
        public void testUnify5OK()
        {
            // <A(B(v),C(u,v)), A(B(w),C(w,D(x,))>
            // * "( Var(alpha)->Var(beta) ) -> Pointer(alpha)"
            TypeExpression alpha   = TypeVariable.NewTypeVariable;
            TypeExpression beta    = TypeVariable.NewTypeVariable;
            MethodType     type1   = new MethodType(new ArrayType(alpha));
            MethodType     typeAux = new MethodType(beta);

            typeAux.AddParameter(alpha);
            type1.AddParameter(typeAux);

            // * "( (double->double)->Var(gamma) ) -> Pointer(Var(gamma))"
            TypeExpression gamma    = TypeVariable.NewTypeVariable;
            MethodType     type2    = new MethodType(new ArrayType(gamma));
            MethodType     typeAux1 = new MethodType(gamma);
            MethodType     typeAux2 = new MethodType(DoubleType.Instance);

            typeAux2.AddParameter(DoubleType.Instance);
            typeAux1.AddParameter(typeAux2);
            type2.AddParameter(typeAux1);

            Unify(type1, type2);
        }
        private MethodDefinition CreateMethod(string fullMethodIndentificator, string originalMethodIndentificator, MethodDefinition originalMethodDefinition, TypeExpression[] args, BaseCallExpression node)
        {
            if (!specilizedMethods.ContainsKey(fullMethodIndentificator))
            {
                String methodIndentificator     = fullMethodIndentificator.Replace(originalMethodDefinition.FullName, originalMethodDefinition.Identifier);
                List <MethodDefinition> methods = new List <MethodDefinition>();
                foreach (TypeExpression[] listOfArgs in GetTypes(args))
                {
                    String           currentMethodIdentificator = MethodIndentificator(originalMethodDefinition.FullName, listOfArgs);
                    MethodDefinition md;
                    if (currentMethodIdentificator.Equals(originalMethodIndentificator))
                    {
                        md = originalMethodDefinition;
                    }
                    else
                    {
                        md = SpecilizeMethod(currentMethodIdentificator, originalMethodDefinition, listOfArgs);
                    }
                    if (md != null && !methods.Any(m => m.ILTypeExpression.Equals(md.ILTypeExpression)))
                    {
                        methods.Add(md);
                    }
                }

                MethodType originalMethodType = (MethodType)originalMethodDefinition.TypeExpr;
                isCurrentMethodDynamic = IsCurrentMethodDynamic(originalMethodType);
                MethodType newMethodType = new MethodType(originalMethodType.Return);
                Location   location      = originalMethodDefinition.IdentifierExp.Location;
                SingleIdentifierExpression newSingleIdentifierExpression = new SingleIdentifierExpression(methodIndentificator, location);
                Block newBlock = new Block(location);

                IList <InvocationExpression> invocations     = new List <InvocationExpression>();
                IList <CastExpression>       castExpressions = new List <CastExpression>();
                int methodsCount = 0;
                foreach (var methodDefinition in methods)
                {
                    MethodType           methodType         = (MethodType)methodDefinition.TypeExpr;
                    IList <IsExpression> isExpressions      = new List <IsExpression>();
                    CompoundExpression   compoundExpression = new CompoundExpression(location);

                    for (int i = 0; i < methodDefinition.ParametersInfo.Count; i++)
                    {
                        SingleIdentifierExpression identifier = new SingleIdentifierExpression(methodDefinition.ParametersInfo[i].Identifier, location);
                        identifier.IndexOfSSA = 0;
                        if (args[i] is UnionType || (args[i] is TypeVariable && ((TypeVariable)args[i]).Substitution is UnionType))
                        {
                            IsExpression isExpression = new IsExpression(identifier,
                                                                         methodType.GetParameter(i).Freeze().ILType(), location);
                            isExpression.TypeExpr = methodType.GetParameter(i).Freeze();
                            isExpressions.Add(isExpression);

                            CastExpression castExpression = new CastExpression(isExpression.TypeExpr.ILType(),
                                                                               identifier, location);
                            castExpressions.Add(castExpression);
                            castExpression.CastType = isExpression.TypeExpr;
                            compoundExpression.AddExpression(castExpression);
                        }
                        else
                        {
                            compoundExpression.AddExpression(identifier);
                        }
                    }

                    Expression condition = isExpressions[0];
                    if (isExpressions.Count > 1)
                    {
                        for (int i = 1; i < isExpressions.Count; i++)
                        {
                            condition = new LogicalExpression(condition, isExpressions[i], LogicalOperator.And, location);
                        }
                    }

                    InvocationExpression invocationExpression = new InvocationExpression(methodDefinition.IdentifierExp, compoundExpression, location);
                    invocations.Add(invocationExpression);
                    ReturnStatement returnStatement = new ReturnStatement(invocationExpression, location);
                    if (++methodsCount < methods.Count || isCurrentMethodDynamic)
                    {
                        IfElseStatement ifElseStatement = new IfElseStatement(condition, returnStatement, location);
                        newBlock.AddStatement(ifElseStatement);
                    }
                    else if (!isCurrentMethodDynamic)
                    {
                        newBlock.AddStatement(returnStatement);
                    }
                }
                //If there is any dynamic union type then it is necessary invoke the original method
                if (isCurrentMethodDynamic)
                {
                    CompoundExpression compoundExpression = new CompoundExpression(location);
                    foreach (var parameter in originalMethodDefinition.ParametersInfo)
                    {
                        SingleIdentifierExpression identifier = new SingleIdentifierExpression(parameter.Identifier, location);
                        identifier.IndexOfSSA = 0;
                        compoundExpression.AddExpression(identifier);
                    }
                    newBlock.AddStatement(new ReturnStatement(new InvocationExpression(new SingleIdentifierExpression(originalMethodDefinition.Identifier, location), compoundExpression, location), location));
                }

                MethodDefinition newMethodDefinition = new MethodDefinition(newSingleIdentifierExpression, newBlock,
                                                                            originalMethodDefinition.ReturnTypeInfo, originalMethodDefinition.ParametersInfo,
                                                                            originalMethodDefinition.ModifiersInfo, location);

                newMethodDefinition.FullName            = fullMethodIndentificator;
                newMethodType.MemberInfo                = new AccessModifier(originalMethodType.MemberInfo.Modifiers, newSingleIdentifierExpression.Identifier, newMethodType, false);
                newMethodType.MemberInfo.Class          = originalMethodType.MemberInfo.Class;
                newMethodType.MemberInfo.TypeDefinition = originalMethodType.MemberInfo.TypeDefinition;

                for (int i = 0; i < originalMethodType.ParameterListCount; i++)
                {
                    newMethodType.AddParameter(args[i].Simplify());
                }

                newMethodType.ASTNode        = newMethodDefinition;
                newMethodDefinition.TypeExpr = newMethodType;
                newMethodDefinition.TypeExpr.BuildFullName();
                newMethodDefinition.TypeExpr.BuildTypeExpressionString(4);

                TypeDefinition originalTypeDefinition = newMethodType.MemberInfo.TypeDefinition;
                originalTypeDefinition.AddMethod(newMethodDefinition);
                UserType originalClass = newMethodType.MemberInfo.Class;

                originalClass.AddMember(methodIndentificator, newMethodType.MemberInfo);
                newMethodDefinition.Accept(new VisitorSymbolIdentification(null), null);
                bool previousDynamism = DynVarOptions.Instance.EverythingDynamic;
                DynVarOptions.Instance.EverythingDynamic = false;
                newMethodDefinition.Accept(visitorTypeInference, null);
                DynVarOptions.Instance.EverythingDynamic = previousDynamism;
                foreach (var invocation in invocations)
                {
                    if (invocation.ActualMethodCalled is UnionType)
                    {
                        invocation.ActualMethodCalled = ((UnionType)invocation.ActualMethodCalled).TypeSet[1];
                    }
                }
                foreach (var castExpression in castExpressions)
                {
                    ((SingleIdentifierExpression)castExpression.Expression).FrozenTypeExpression = new ClassType("System.Object");
                    castExpression.Expression.ExpressionType = new ClassType("System.Object");
                }


                specilizedMethods.Add(fullMethodIndentificator, newMethodDefinition);
                return(newMethodDefinition);
            }
            return(specilizedMethods[fullMethodIndentificator]);
        }
Beispiel #7
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);
        }