protected override Expression VisitMember(MemberExpression node) { var visitor = new InvokingVisitor(_objectInstance); visitor.Visit(node); Resolution += $"'{visitor.Results[0]}'"; return(node); }
protected override Expression VisitMethodCall(MethodCallExpression node) { var parameterVisitor = new InvokingVisitor(_objectInstance); node.Arguments.ForEach(arg => parameterVisitor.Visit(arg)); Results.Add(node.Method.Invoke(_objectInstance, parameterVisitor.Results.ToArray())); return(node); }
protected override Expression VisitMethodCall(MethodCallExpression node) { var objectInstance = (node.Object is ConstantExpression constant) ? constant.Value : _objectInstance; var methodCallFormatter = new Func <string, ReadOnlyCollection <Expression>, string>((name, args) => { var arguments = args.Select(arg => { var argVisitor = new DelegateVisitor(_converter, _methodDepth + 1, objectInstance); argVisitor.Visit(arg); return(argVisitor.Resolution); }); return(string.Format(_converter._methodCallFormat, name, string.Join(", ", arguments))); }); var supportMethods = new Func <IEnumerable <MethodInfo> >(() => typeof(Installation).GetMethods(BindingFlags.Instance | BindingFlags.Public) .Where(m => m.GetCustomAttribute <BuiltInSymbolAttribute>() != null)); switch (_methodDepth) { case 1: var supportMethod = supportMethods().FirstOrDefault(m => m.Name == node.Method.Name); if (supportMethod == null) { var handler = BindingSearch.Flags .Select(f => objectInstance.GetType().GetMethod(node.Method.Name, f)) .FirstOrDefault(m => m != null); if (handler == null) { var msg = $"Only class instance methods may be invoked; {node.Method.Name} is not supported"; throw new NotSupportedException(msg); } _converter._visitMethodHandler(node.Method); } break; case 2: var expandConstantMethod = supportMethods().FirstOrDefault(m => m.Name == nameof(Installation.ExpandConstant)); if (expandConstantMethod == null || node.Method.MetadataToken != expandConstantMethod.MetadataToken) { var msg = $"Only the method call {nameof(Installation.ExpandConstant)} is allowed at this depth; {node.Method.Name} is not supported"; throw new NotSupportedException(msg); } break; default: methodCallFormatter = (name, args) => { var visitor = new InvokingVisitor(objectInstance); visitor.Visit(node); return(visitor.Results[0] is string?$"'{visitor.Results[0]}'" : visitor.Results[0].ToString()); }; break; } var methodName = node.Method.GetCustomAttribute <AliasAttribute>()?.Name ?? node.Method.Name; Resolution += methodCallFormatter(methodName, node.Arguments); return(node); }