Esempio n. 1
0
            protected override Expression VisitMember(MemberExpression node)
            {
                var visitor = new InvokingVisitor(_objectInstance);

                visitor.Visit(node);

                Resolution += $"'{visitor.Results[0]}'";

                return(node);
            }
Esempio n. 2
0
            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);
            }
Esempio n. 3
0
            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);
            }