private bool IsCurrentMethodDynamic(MethodType originalMethodType)
 {
     for (int i = 0; i < originalMethodType.ParameterListCount; i++)
     {
         if (originalMethodType.GetParameter(i).IsDynamic)
         {
             return(true);
         }
     }
     return(false);
 }
        public override Object Visit(InvocationExpression node, Object obj)
        {
            MethodType originalMemberTypeExpression = node.ActualMethodCalled as MethodType;

            if (node.Arguments.ExpressionCount == 0 || originalMemberTypeExpression == null || !originalMemberTypeExpression.HasTypeVariables())
            {
                return(null);
            }

            TypeExpression[] args = this.compoundExpressionToArray(node.Arguments); //VisitorInference pass when error??
            if (args == null)
            {
                return(null);
            }

            MethodDefinition originalMethodDefinition = originalMemberTypeExpression.ASTNode as MethodDefinition;

            if (originalMethodDefinition == null)
            {
                return(null);
            }

            TypeExpression[] originalParamsType = new TypeExpression[originalMemberTypeExpression.ParameterListCount];
            for (int i = 0; i < originalMemberTypeExpression.ParameterListCount; i++)
            {
                originalParamsType[i] = originalMemberTypeExpression.GetParameter(i);
            }
            var originalMethodIndentificator = MethodIndentificator(originalMethodDefinition.FullName, originalParamsType, true);
            var methodIndentificator         = MethodIndentificator(originalMethodDefinition.FullName, args);

            if (methodIndentificator.Equals(originalMethodIndentificator)) //Method does not need to be specialized
            {
                if (!specilizedMethods.ContainsKey(originalMethodIndentificator))
                {
                    specilizedMethods[originalMethodIndentificator] = originalMethodDefinition;
                }
                return(null);
            }

            bool             specializeOrCreate = !HasUnionTypes(originalMethodDefinition.FullName, methodIndentificator);
            MethodDefinition method             = specializeOrCreate ? SpecilizeMethod(methodIndentificator, originalMethodDefinition, args) : CreateMethod(methodIndentificator, originalMethodIndentificator, originalMethodDefinition, args, node);

            if (method != null)
            {
                UpdateActualMethodCalled(node, method, specializeOrCreate);
                method.Accept(this, obj);
            }
            else if (pendingMethods.ContainsKey(methodIndentificator))
            {
                pendingMethods[methodIndentificator].Add(node);
            }
            return(null);
        }
        public override Object Visit(NewExpression node, Object obj)
        {
            MethodType originalMemberTypeExpression = node.ActualMethodCalled as MethodType;

            if (node.Arguments.ExpressionCount == 0 || originalMemberTypeExpression == null || !originalMemberTypeExpression.HasTypeVariables())
            {
                return(null);
            }

            TypeExpression[] args = this.compoundExpressionToArray(node.Arguments); //VisitorInference pass when error??
            if (args == null)
            {
                return(null);
            }

            MethodDefinition originalMethodDefinition = originalMemberTypeExpression.ASTNode as MethodDefinition;

            if (originalMethodDefinition == null)
            {
                return(null);
            }

            TypeExpression[] originalParamsType = new TypeExpression[originalMemberTypeExpression.ParameterListCount];
            for (int i = 0; i < originalMemberTypeExpression.ParameterListCount; i++)
            {
                originalParamsType[i] = originalMemberTypeExpression.GetParameter(i);
            }
            var originalMethodIndentificator = MethodIndentificator(originalMethodDefinition.FullName, originalParamsType, true);
            var methodIndentificator         = MethodIndentificator(originalMethodDefinition.FullName, args);

            if (methodIndentificator.Equals(originalMethodIndentificator)) //Method does not need to be specialized
            {
                if (!specilizedMethods.ContainsKey(originalMethodIndentificator))
                {
                    specilizedMethods[originalMethodIndentificator] = originalMethodDefinition;
                }
                return(null);
            }

            if (HasUnionTypes(originalMethodDefinition.FullName, methodIndentificator))
            {
                return(null);                                                                        //Any parameter is a UnionType, It is imposible to specilize constructor.
            }
            MethodDefinition method = SpecilizeMethod(methodIndentificator, originalMethodDefinition, args);

            if (method != null)
            {
                UpdateActualMethodCalled(node, method, true);
            }
            return(null);
        }
Beispiel #4
0
        internal override void RuntimeCheckArguments(InvocationExpression node, Object objArgs, MethodType actualMethodCalled, List <string> nextMethod)
        {
            for (int j = 0; j < node.Arguments.ExpressionCount; j++)
            {
                node.Arguments.GetExpressionElement(j).Accept(this, objArgs);
                actualMethodCalled.GetParameter(j).AcceptOperation(new CGRuntimeCheckArgumentOperation <T>(this.indent, this.codeGenerator, nextMethod), null);
                //if ((!(actualMethodCalled.GetParameter(j).IsValueType()))
                //   || (actualMethodCalled.GetParameter(j) is BoolType) || (actualMethodCalled.GetParameter(j) is CharType))
                //{
                //   this.codeGenerator.dup(this.indent);
                //   this.codeGenerator.isinst(this.indent, actualMethodCalled.GetParameter(j));
                //   // if check fail then check nextMethod
                //   nextMethod.Add(this.codeGenerator.NewLabel);
                //   this.codeGenerator.brfalse(this.indent, nextMethod[nextMethod.Count - 1]);
                //   if (actualMethodCalled.GetParameter(j).IsValueType())
                //      this.codeGenerator.UnboxAny(this.indent, actualMethodCalled.GetParameter(j));
                //}
                //else
                //{
                //   // Param is Int. Is the argument an int?
                //   if (actualMethodCalled.GetParameter(j) is IntType)
                //   {
                //      string nextArgument = this.codeGenerator.NewLabel;
                //      CharType.Instance.AcceptOperation(new CGRuntimeCheckTypeExpressionOperation(this.indent, this.codeGenerator, nextArgument, false));
                //      IntType.Instance.AcceptOperation(new CGRuntimeCheckTypeExpressionOperation(this.indent, this.codeGenerator, nextArgument, false));

                //      nextMethod.Add(this.codeGenerator.NewLabel);
                //      this.codeGenerator.br(this.indent, nextMethod[nextMethod.Count - 1]);
                //      this.codeGenerator.WriteLabel(nextArgument);
                //   }
                //   else
                //   {
                //      // Param is Double. Is the argument a double?
                //      if (actualMethodCalled.GetParameter(j) is DoubleType)
                //      {
                //         string nextArgument = this.codeGenerator.NewLabel;

                //         CharType.Instance.AcceptOperation(new CGRuntimeCheckTypeExpressionOperation(this.indent, this.codeGenerator, nextArgument, true));
                //         IntType.Instance.AcceptOperation(new CGRuntimeCheckTypeExpressionOperation(this.indent, this.codeGenerator, nextArgument, true));
                //         DoubleType.Instance.AcceptOperation(new CGRuntimeCheckTypeExpressionOperation(this.indent, this.codeGenerator, nextArgument, true));

                //         nextMethod.Add(this.codeGenerator.NewLabel);
                //         this.codeGenerator.br(this.indent, nextMethod[nextMethod.Count - 1]);
                //         this.codeGenerator.WriteLabel(nextArgument);
                //      }
                //   }
                //}
            }
        }
        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);
        }
Beispiel #6
0
        public override object Exec(MethodType m, object arg)
        {
            MethodType method = this.typeExpression as MethodType;

            if (method == null)
            {
                return(false);
            }
            if (m.ParameterListCount != method.ParameterListCount)
            {
                return(false);
            }
            for (int i = 0; i < method.ParameterListCount; i++)
            {
                if (!(bool)m.GetParameter(i).AcceptOperation(new EqualsForOverloadOperation(method.GetParameter(i)), arg))
                {
                    return(false);
                }
            }
            return(true);
        }
Beispiel #7
0
        private StaDynSignature CreateSignature(ITextBuffer textBuffer, MethodType method, string methodDoc, ITrackingSpan span)
        {
            string name        = method.MemberInfo.MemberIdentifier;
            string returnType  = method.Return.FullName;
            string description = returnType + " " + name;

            string methodSig = description;

            StaDynSignature sig = new StaDynSignature(textBuffer, methodSig, methodDoc, null);

            textBuffer.Changed += new EventHandler <TextContentChangedEventArgs>(sig.OnSubjectBufferChanged);

            List <IParameter> paramList = new List <IParameter>();

            //Generate a correct signature
            methodSig += " ( ";

            int locusSearchStart = 0;

            if (method.ASTNode != null)
            {
                //ParametersInfo available (There is access to the definition of the method)
                foreach (Parameter param in method.ASTNode.ParametersInfo)
                {
                    string pName        = param.Identifier;
                    string pDescription = param.ParamType + " " + pName;
                    methodSig += " " + pDescription + " ,";
                    int locusStart = methodSig.IndexOf(pDescription, locusSearchStart);

                    if (locusStart >= 0)
                    {
                        Span locus = new Span(locusStart, pDescription.Length);
                        locusSearchStart = locusStart + pDescription.Length;
                        paramList.Add(new StaDynParameter(pDescription, locus, pDescription, sig));
                    }
                }
            }
            else
            {
                //ParametersInfo not available (There is not access to the definition of the method)
                for (int i = 0; i < method.ParameterListCount; i++)
                {
                    string pDescription = method.GetParameter(i).FullName;
                    methodSig += " " + pDescription + " ,";
                    int locusStart = methodSig.IndexOf(pDescription, locusSearchStart);
                    if (locusStart >= 0)
                    {
                        Span locus = new Span(locusStart, pDescription.Length);
                        locusSearchStart = locusStart + pDescription.Length;
                        paramList.Add(new StaDynParameter(pDescription, locus, pDescription, sig));
                    }
                }
            }

            //Complete the method signature
            int lastComma = methodSig.LastIndexOf(',');

            if (lastComma >= 0)
            {
                methodSig = methodSig.Remove(lastComma);
            }

            methodSig += ")";

            //Update signature
            sig.Content          = methodSig;
            sig.Parameters       = new ReadOnlyCollection <IParameter>(paramList);
            sig.ApplicableToSpan = span;
            sig.ComputeCurrentParameter();
            return(sig);
        }
        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 #9
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);
        }