Esempio n. 1
0
        private void WriteLambdas(LambdaExpression lambda, TextFormatter formatter)
        {
            var lambdas = ExpressionSearcher.Search(lambda, e => e.NodeType == ExpressionType.Lambda).Cast <LambdaExpression>().DistinctBy(l => l.Name).ToList();

            for (var i = 0; i < lambdas.Count; i++)
            {
                if (string.IsNullOrEmpty(lambdas[i].Name))
                {
                    throw new InvalidOperationException($"Lambda {lambdas[i]} is missing a name");
                }

                var methodBuilder = typeBuilder.DefineMethod(lambdas[i].Name, MethodAttributes.Public | MethodAttributes.Static);

                lambda.Compile();

                var debugLambda = GetDebugLambda(lambdas[i], formatter);

                debugLambda.Compile();

                debugLambda.CompileToMethod(methodBuilder, pdbGenerator);

                if (i < lambdas.Count - 1)
                {
                    formatter.WriteLine();
                }
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Identifies conditions to include from a <see cref="WhereLinqExpression"/>.
        /// </summary>
        /// <param name="node">The binary expression to analyze.</param>
        /// <returns>The original binary expression.</returns>
        protected override Expression VisitBinary(BinaryExpression node)
        {
            switch (node.NodeType)
            {
            case ExpressionType.AndAlso:
            case ExpressionType.OrElse:
                Visit(node.Left);
                Visit(node.Right);
                return(node);

            default:
                var types = ExpressionSearcher.GetTypes(node);

                if (types.Contains(ExpressionType.AndAlso) || types.Contains(ExpressionType.OrElse))
                {
                    Visit(node.Left);
                    Visit(node.Right);
                    return(node);
                }
                else
                {
                    var visited = UnaryFixer.Fix(node);

                    Conditions.Add(visited);

                    return(node);
                }
            }
        }
        private bool CanEvaluateLocally(List <Expression> listInits)
        {
            foreach (var init in listInits)
            {
                var listChildren = ExpressionSearcher.Search(init, e => true);

                if (listChildren.Any(c => !CanBeEvaluatedLocally(c)))
                {
                    return(false);
                }
            }

            return(true);
        }
Esempio n. 4
0
        protected void Execute(Expression <Func <Sensor, bool> > predicate, string url, ExpressionType nodeType)
        {
            var types = ExpressionSearcher.GetTypes(predicate);

            Assert.IsTrue(types.Any(t => t == nodeType), $"Did not have an expression of type {nodeType}. Types found: " + string.Join(", ", types));

            var urls = new[]
            {
                TestHelpers.RequestSensor(url)
            };

            var client = GetClient(urls.ToArray());

            var result = client.QuerySensors().Where(predicate).ToList();
        }
        private bool IsSingleCondition(Expression condition)
        {
            var subconditions = ExpressionSearcher.Search(
                condition,
                e => ConditionReducer.IsBinaryCondition(e) || ConditionReducer.IsMethodCondition(e)
                );

            var isSingle = subconditions.Count == 1;

            if (!isSingle && strict)
            {
                throw Error.AmbiguousCondition(condition, subconditions);
            }

            return(isSingle);
        }
Esempio n. 6
0
        internal static Exception UnsupportedFilterExpression(Expression expr, Expression ignoredExpression, IllegalType illegalType)
        {
            var exprProperties        = ExpressionSearcher.Search <PropertyExpression>(expr).Cast <PropertyExpression>().ToList();
            var ignoredExprProperties = ExpressionSearcher.Search <PropertyExpression>(ignoredExpression).Cast <PropertyExpression>().ToList();

            switch (illegalType)
            {
            //We don't reach this case because we always throw based on having multiple PropertyExpressions before
            //we can actually determine both expressions were the same
            case IllegalType.LeftRightSameProperty:
                if (ignoredExprProperties.Count == 0)
                {
                    return(new NotSupportedException(string.Format(unsupportedFilterExpression_LeftRightZero, Clean(ignoredExpression))));
                }

                return(new NotSupportedException(string.Format(
                                                     unsupportedFilterExpression_LeftRightSame,
                                                     ignoredExprProperties.First().PropertyInfo.Name,
                                                     Clean(ignoredExpression),
                                                     ignoredExpression.GetType()
                                                     )));

            case IllegalType.NotSingleProperty:
                return(new NotSupportedException(string.Format(
                                                     unsupportedFilterExpression_NoProperty,
                                                     Clean(ignoredExpression)
                                                     )));

            case IllegalType.AndSameProperty:
                return(new NotSupportedException(string.Format(unsupportedFilterExpression_AndSame, exprProperties.Single().PropertyInfo.Name)));

            case IllegalType.OrDifferentProperty:
                return(new NotSupportedException(string.Format(
                                                     unsupportedFilterExpression_OrMultiple,
                                                     exprProperties.Single().PropertyInfo.Name,
                                                     ignoredExprProperties.Single().PropertyInfo.Name
                                                     )));

            case IllegalType.ExclusiveOr:
                return(new NotSupportedException(string.Format(
                                                     unsupportedFilterExpression_ExclusiveOr,
                                                     exprProperties.Single().PropertyInfo.Name
                                                     )));
            }

            throw new NotImplementedException($"Don't know how to handle illegal type '{illegalType}'");
        }
Esempio n. 7
0
        protected void Execute(Expression <Func <Sensor, bool> > predicate, string url, ExpressionType nodeType)
        {
            var types = ExpressionSearcher.GetTypes(predicate);

            Assert.IsTrue(types.Any(t => t == nodeType), $"Did not have an expression of type {nodeType}. Types found: " + string.Join(", ", types));

            var urls = new[]
            {
                UnitRequest.Sensors($"count=500" + (string.IsNullOrEmpty(url) ? url : $"&{url}"), UrlFlag.Columns)
            };

            var client = GetClient(urls.ToArray());

            var result = client.Item1.QuerySensors().Where(predicate).ToList();

            client.Item2.AssertFinished();
        }
        private bool HasOnlyLegalExpressionTypes(Expression filter)
        {
            var types            = ExpressionSearcher.GetTypes(filter);
            var unsupportedTypes = types.Where(t => t == ExpressionType.ArrayLength || t == ExpressionType.Throw || t == ExpressionType.DebugInfo).ToList();

            if (unsupportedTypes.Count > 0)
            {
                Logger.Log("Expression contains an illegal expression node(s) " + string.Join(", ", unsupportedTypes) + ". Ignoring filter.", Indentation.Six);

                if (strict)
                {
                    throw Error.UnsupportedExpressionType(unsupportedTypes, filter);
                }

                return(false);
            }

            return(true);
        }
        private void ValidateCandidates(Expression expression, List <Expression> candidates)
        {
            List <Expression> toRemove = new List <Expression>();

            foreach (var candidate in candidates)
            {
                if (toRemove.Contains(candidate))
                {
                    continue;
                }

                if (typeof(IEnumerable).IsAssignableFrom(candidate.Type) && candidate.NodeType == ExpressionType.New)
                {
                    var parents = ExpressionSearcher.GetParents(candidate, expression);

                    var listInit = parents.Where(p => p.NodeType == ExpressionType.ListInit).ToList();

                    if (!CanEvaluateLocally(listInit))
                    {
                        toRemove.Add(candidate);

                        foreach (var c in candidates)
                        {
                            if (parents.Any(p => p == c))
                            {
                                toRemove.AddRange(parents.Where(p => p == c));
                            }
                        }
                    }
                }
            }

            if (toRemove.Count > 0)
            {
                Logger.Log($"Removing {toRemove.Count} incorrectly flagged candidates", Indentation.Two, toRemove);

                foreach (var expr in toRemove)
                {
                    candidates.Remove(expr);
                }
            }
        }
Esempio n. 10
0
        private void GenerateMethods(LambdaExpression lambda)
        {
            var stringWriter = new StringWriter();
            var formatter    = new TextFormatter(stringWriter);
            var writer       = new CSharpWriter(formatter, null);

            var usings = ExpressionSearcher.Search(lambda, e => true).Select(e => e.Type.Namespace).Distinct().ToList();

            var ordered = usings.OrderBy(s => s).OrderBy(s => !s.StartsWith("System")).ToList();

            foreach (var @using in ordered)
            {
                formatter.Write("using");
                formatter.WriteSpace();
                formatter.Write(@using);
                formatter.Write(";");
                formatter.WriteLine();
            }

            formatter.WriteLine();

            formatter.Write("namespace");
            formatter.WriteSpace();
            formatter.Write(name);
            formatter.WriteLine();

            writer.VisitBlock(() =>
            {
                formatter.Write($"public class {typeBuilder.Name}");
                formatter.WriteLine();

                writer.VisitBlock(() =>
                {
                    WriteLambdas(lambda, formatter);
                });

                formatter.WriteLine();
            });

            File.WriteAllText(symbolDocument.FileName, stringWriter.ToString());
        }
        private bool HasExtraMemberExpressions(Expression filter)
        {
            var members = ExpressionSearcher.Search(filter, e => e is MemberExpression, e => e is PropertyExpression).Cast <MemberExpression>().ToList();

            var illegalMembers = members.Where(m => !LegalPropertyMember(m)).ToList();

            //Catch instances where someone went (s.prop.SubProp == val)
            if (illegalMembers.Count > 0)
            {
                Logger.Log($"Expression contains {illegalMembers.Count} extraneous {nameof(MemberExpression)} expressions. Ignoring filter.", Indentation.Six);

                if (strict)
                {
                    throw Error.InvalidMemberCount(filter, illegalMembers);
                }

                return(false);
            }

            return(true);
        }
        private List <List <SearchFilter> > GetFilters(List <Expression> conditions)
        {
            Logger.Log("Evaluating filter candidates", Indentation.Four);

            //Remove conditions that were derived from methods that are not LinqExpressions.
            //For example, in Take(3).Where(s => s.Id == 1001), s.Id is a native MemberExpression
            //that was never transformed into a PropertyExpression. This is almost identical to
            //the check that is done in IsLegalFilter, however by immediately removing such candidates
            //we don't flag HasIllegalServerFilters, thereby allowing us to still do things such as set a Count
            conditions = conditions.Where(c =>
            {
                var valid = ExpressionSearcher.Search <PropertyExpression>(c).Count > 0;

                if (!valid)
                {
                    Logger.Log($"Removing condition {c} as it does not contain any property expressions", Indentation.Five);

                    if (strict)
                    {
                        throw Error.InvalidPropertyCount(c, new List <PropertyExpression>());
                    }
                }

                return(valid);
            }).ToList();

            var legalFilters = conditions
                               .Where(IsLegalFilter)
                               .Select(GetReducedCondition)
                               .Where(IsSingleCondition)
                               .SelectMany(GetSearchFilter).ToList();

            var adjustedFilters = queryHelper?.AdjustFilters(legalFilters) ?? new List <List <SearchFilter> >
            {
                legalFilters
            };

            return(adjustedFilters);
        }
        private bool IsLegalFilterInternal(Expression filter)
        {
            Logger.Log($"Determining whether expression '{filter}' is a legal filter", Indentation.Five);

            var properties = ExpressionSearcher.Search(filter, e => e is PropertyExpression).Cast <PropertyExpression>().ToList();

            if (!HasSinglePropertyExpression(filter, properties))
            {
                return(false);
            }

            if (!HasExtraMemberExpressions(filter))
            {
                return(false);
            }

            if (!HasOnlyLegalExpressionTypes(filter))
            {
                return(false);
            }

            var property = properties.Single();
            var parents  = ExpressionSearcher.GetParents(property, filter).ToList();

            if (!HasOnlyLegalCasts(property, parents))
            {
                return(false);
            }

            if (!HasOnlyLegalParents(filter, parents))
            {
                return(false);
            }

            Logger.Log("Filter did not match any exclusion criteria. Including filter", Indentation.Six);
            return(true);
        }
        private List <PropertyExpression> GetProperties(Expression expression)
        {
            var results = ExpressionSearcher.Search <PropertyExpression>(expression);

            return(results.Cast <PropertyExpression>().ToList());
        }
 private bool IsAndOrOr(Expression node)
 {
     return(ExpressionSearcher.Search(node, e => e.NodeType == ExpressionType.AndAlso || node.NodeType == ExpressionType.OrElse).Any());
 }