private void GetMethodCallData(DoshikParser.MethodCallContext methodCallCtx, MethodCallExpressionNodeData dataToPopulate)
        {
            dataToPopulate.Name = methodCallCtx.methodName.Text;

            dataToPopulate.TypeArguments.AddRange(GetTypeArguments(methodCallCtx.typeArguments()));

            dataToPopulate.Parameters.AddRange(GetMethodCallParameters(methodCallCtx.methodCallParams()));
        }
示例#2
0
        private IExpression HandleNewCallExpressionNode(NewCallExpressionNode node)
        {
            var methodCallData = new MethodCallExpressionNodeData
            {
                Name = "ctor"
            };

            methodCallData.Parameters.AddRange(node.Parameters);

            return(CreateStaticMethodCallExpression(node.Type, methodCallData));
        }
示例#3
0
        private IExpression CreateStaticMethodCallExpressionForUnaryOperator(string methodName, IExpressionNode operand)
        {
            var operandExpression = FindExpressionByExpressionNode(operand, false);

            var methodCallData = new MethodCallExpressionNodeData
            {
                Name = methodName
            };

            methodCallData.Parameters.Add(new MethodCallParameterExpressionNodeData {
                Expression = operand
            });

            return(CreateStaticMethodCallExpression(operandExpression.ReturnOutputSlot.Type, methodCallData));
        }
示例#4
0
        private IExpression CreateStaticMethodCallExpressionForBinaryOperator(string methodName, IExpressionNode left, IExpressionNode right)
        {
            var leftExpression = FindExpressionByExpressionNode(left, false);

            var methodCallData = new MethodCallExpressionNodeData
            {
                Name = methodName
            };

            methodCallData.Parameters.Add(new MethodCallParameterExpressionNodeData {
                Expression = left
            });
            methodCallData.Parameters.Add(new MethodCallParameterExpressionNodeData {
                Expression = right
            });

            return(CreateStaticMethodCallExpression(leftExpression.ReturnOutputSlot.Type, methodCallData));
        }
示例#5
0
        private IExpression CreateMethodCallExpression(DataType typeForStaticCall, IExpressionNode instanceForInstanceCall, MethodCallExpressionNodeData methodCallData)
        {
            if (methodCallData.TypeArguments.Count > 0)
            {
                throw _compilationContext.ThrowCompilationError("method type arguments are not supported");
            }

            var isStatic = instanceForInstanceCall == null;

            IExpression instance = isStatic
                ? null
                : FindExpressionByExpressionNode(instanceForInstanceCall, false);

            DataType type = isStatic
                ? typeForStaticCall
                : instance.ReturnOutputSlot.Type;

            var result = isStatic
                ? (IMethodCallExpression) new StaticMethodCallExpression()
                : new InstanceMethodCallExpression();

            var callParameters = new List <MethodCallParameterExpressionNodeData>(methodCallData.Parameters.Count + (isStatic ? 0 : 1));

            if (!isStatic)
            {
                callParameters.Add(new MethodCallParameterExpressionNodeData {
                    Expression = instanceForInstanceCall
                });
            }

            callParameters.AddRange(methodCallData.Parameters);

            var findOverloadPararmeters = new List <TypeLibrary.FindOverloadParameter>(callParameters.Count);

            // Проходим по всем параметрам у вызова метода
            for (int callParametersIndex = 0; callParametersIndex < callParameters.Count; callParametersIndex++)
            {
                var methodCallParameter = callParameters[callParametersIndex];

                // Добавляем input слот к текущему выражению (он уже существует как output у выражения, соответствующего этому параметру)

                var slot = FindExpressionByExpressionNode(methodCallParameter.Expression, false).ReturnOutputSlot;

                slot.InputSideExpression = result;
                result.InputSlots.Add(slot);

                var isInstanceParameter = !isStatic && callParametersIndex == 0;

                if (!isInstanceParameter)
                {
                    findOverloadPararmeters.Add(new TypeLibrary.FindOverloadParameter {
                        IsOut = methodCallParameter.IsOut, Type = slot.Type.ExternalType
                    });
                }
            }

            var foundOverload = _compilationContext.TypeLibrary.FindBestMethodOverload(isStatic, type.ExternalType, methodCallData.Name, findOverloadPararmeters);

            if (foundOverload.OverloadCount == 0)
            {
                throw _compilationContext.ThrowCompilationError($"{ (isStatic ? "static" : "instance") } method { methodCallData.Name } not found in { _compilationContext.TypeLibrary.GetApiTypeFullCodeName(type.ExternalType) } type");
            }

            if (foundOverload.BestOverload == null)
            {
                // ToDo: в сообщении указывать сигнатуру перегрузки которая искалась и все сигнатуры которые есть
                throw _compilationContext.ThrowCompilationError($"overload for { (isStatic ? "static" : "instance") } method { methodCallData.Name } not found in { _compilationContext.TypeLibrary.GetApiTypeFullCodeName(type.ExternalType) } type, but found { foundOverload.OverloadCount } other overloads for this method");
            }

            result.MethodOverload = foundOverload.BestOverload;

            // Определяем выходное значение

            var returnValueIsVoid = result.MethodOverload.OutParameterType == null;

            var returnValueType = returnValueIsVoid
                ? _compilationContext.TypeLibrary.FindVoid()
                : _compilationContext.TypeLibrary.FindByExternalType(result.MethodOverload.OutParameterType);

            result.ReturnOutputSlot = new ExpressionSlot(returnValueType, result);

            foreach (var outParameter in result.MethodOverload.ExtraOutParameters)
            {
                result.AdditionalOutputSlots.Add(new ExpressionSlot(_compilationContext.TypeLibrary.FindByExternalType(outParameter.Type), result));
            }

            return(result);
        }
示例#6
0
 private IExpression CreateStaticMethodCallExpression(DataType type, MethodCallExpressionNodeData methodCallData)
 {
     return(CreateMethodCallExpression(type, null, methodCallData));
 }
示例#7
0
 private IExpression CreateInstanceMethodCallExpression(IExpressionNode instanceExpressionNode, MethodCallExpressionNodeData methodCallData)
 {
     return(CreateMethodCallExpression(null, instanceExpressionNode, methodCallData));
 }