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())); }
private IExpression HandleNewCallExpressionNode(NewCallExpressionNode node) { var methodCallData = new MethodCallExpressionNodeData { Name = "ctor" }; methodCallData.Parameters.AddRange(node.Parameters); return(CreateStaticMethodCallExpression(node.Type, methodCallData)); }
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)); }
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)); }
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); }
private IExpression CreateStaticMethodCallExpression(DataType type, MethodCallExpressionNodeData methodCallData) { return(CreateMethodCallExpression(type, null, methodCallData)); }
private IExpression CreateInstanceMethodCallExpression(IExpressionNode instanceExpressionNode, MethodCallExpressionNodeData methodCallData) { return(CreateMethodCallExpression(null, instanceExpressionNode, methodCallData)); }