public override object Exec(MethodType caller, object arg)
        {
            // * Quits if there's some error in the arguments
            if (this.arguments == null)
            {
                return(null);
            }

            // * An instance method cannot be call from a static method without using an object
            if ((!caller.MemberInfo.Modifiers.Contains(Modifier.Static)) && this.methodAnalyzed != null &&
                this.methodAnalyzed.MemberInfo.Modifiers.Contains(Modifier.Static) && this.actualImplicitObject == null)
            {
                ErrorManager.Instance.NotifyError(new InstanceMethodCallFromStaticMethodError(caller.FullName, this.methodAnalyzed.FullName, this.location));
                return(null);
            }

            // * Is Unification necessary?
            if (caller.MemberInfo.Class.HasTypeVariables() || caller.HasTypeVariables())
            {
                // * We infer the return type
                return(MethodType.methodCall(this.actualImplicitObject, caller, this.arguments, this.methodAnalyzed, this.activeSortOfUnification, this.location));
            }

            // h Otherwise...
            // Check the argument number
            if (this.arguments.GetLength(0) != caller.ParameterListCount)
            {
                ErrorManager.Instance.NotifyError(new ArgumentNumberError(caller.MemberInfo.MemberIdentifier, this.arguments.GetLength(0), this.location));
                return(null);
            }
            // Check the argument type
            for (int i = 0; i < caller.ParameterListCount; i++)
            {
                this.arguments[i].AcceptOperation(PromotionOperation.Create(caller.getParam(i), this.methodAnalyzed, this.location), arg);
            }
            // * Returns the return type
            return(caller.Return);
        }
        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);
        }
        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);
        }
Beispiel #4
0
        public override object Exec(MethodType caller, object arg)
        {
            // * Quits if there's some error in the arguments
            if (this.arguments == null)
            {
                return(null);
            }

            // * An instance method cannot be call from a static method without using an object
            if ((!caller.MemberInfo.Modifiers.Contains(Modifier.Static)) && this.methodAnalyzed != null &&
                this.methodAnalyzed.MemberInfo.Modifiers.Contains(Modifier.Static) && this.actualImplicitObject == null)
            {
                ErrorManager.Instance.NotifyError(new InstanceMethodCallFromStaticMethodError(caller.FullName, this.methodAnalyzed.FullName, this.location));
                return(null);
            }

            // * Is Unification necessary?
            if (caller.MemberInfo.Class.HasTypeVariables() || caller.HasTypeVariables())
            {
                return(MethodType.methodCall(this.actualImplicitObject, caller, this.arguments, this.methodAnalyzed, this.activeSortOfUnification, this.location));
            }
            // h Otherwise...
            // Check the argument number
            if (this.arguments.GetLength(0) != caller.ParameterListCount)
            {
                ErrorManager.Instance.NotifyError(new ArgumentNumberError(caller.MemberInfo.MemberIdentifier, this.arguments.GetLength(0), this.location));
                return(null);
            }

            int from = (this.methodAnalyzed != null && this.methodAnalyzed.Constraints != null) ? this.methodAnalyzed.Constraints.Count:0;

            // Check the argument type
            for (int i = 0; i < caller.ParameterListCount; i++)
            {
                this.arguments[i].AcceptOperation(PromotionOperation.Create(caller.getParam(i), this.methodAnalyzed, this.location), arg);
            }
            int to = (this.methodAnalyzed != null && this.methodAnalyzed.Constraints != null) ? this.methodAnalyzed.Constraints.Count : 0;

            if (to > from)
            {
                ConstraintList cl = new ConstraintList();
                for (int i = from; i < to; i++)
                {
                    cl.Add(this.methodAnalyzed.Constraints.Constraints[i]);
                }
                for (int i = to - 1; i >= from; i--)
                {
                    this.methodAnalyzed.Constraints.Constraints.RemoveAt(i);
                }

                InvocationConstraint ic = null;
                foreach (var constraint in this.methodAnalyzed.Constraints.Constraints)
                {
                    ic = constraint as InvocationConstraint;
                    if (ic != null && ic.MethodName.Equals(caller.ToString()))
                    {
                        ic.Add(cl);
                        break;
                    }
                    ic = null;
                }

                if (ic == null)
                {
                    ic = new InvocationConstraint(caller.ToString());
                    ic.Add(cl);
                    this.methodAnalyzed.Constraints.Add(ic);
                }
            }

            // * Returns the return type
            return(caller.Return);
        }