Exemple #1
0
        public override void Enumerate(IMemberCompletionAcceptor acceptor)
        {
            if (acceptor == null)
            {
                throw ExceptionBuilder.ArgumentNull("acceptor");
            }

            NamedConstantExpression namedConstantExpression = _expressionBeforeDot as NamedConstantExpression;
            ParameterExpression     parameterExpression     = _expressionBeforeDot as ParameterExpression;

            IList <PropertyBinding> properties = null;

            if (namedConstantExpression == null && parameterExpression == null)
            {
                // The properties must be provided by a regular property provider.

                IPropertyProvider propertyProvider = _scope.DataContext.MetadataContext.PropertyProviders[_expressionBeforeDot.ExpressionType];

                if (propertyProvider != null)
                {
                    properties = propertyProvider.GetProperties(_expressionBeforeDot.ExpressionType);
                }
            }
            else
            {
                // The expression before the dot is named constant or a parameter. In both cases, the properties
                // could be contributed as custom properties.

                if (namedConstantExpression != null)
                {
                    properties = namedConstantExpression.Constant.CustomProperties;
                }
                else
                {
                    properties = parameterExpression.Parameter.CustomProperties;
                }
            }

            if (properties != null)
            {
                foreach (PropertyBinding propertyBinding in properties)
                {
                    acceptor.AcceptProperty(propertyBinding);
                }
            }

            // Now contribute any methods

            IMethodProvider methodProvider = _scope.DataContext.MetadataContext.MethodProviders[_expressionBeforeDot.ExpressionType];

            if (methodProvider != null)
            {
                MethodBinding[] methods = methodProvider.GetMethods(_expressionBeforeDot.ExpressionType);
                foreach (MethodBinding methodBinding in  methods)
                {
                    acceptor.AcceptMethod(methodBinding);
                }
            }
        }
Exemple #2
0
        void Literal(out OqlExpression expression)
        {
            OqlExpression result = null;

            switch (la.kind)
            {
            case 2: {
                Get();
                result = new NumberExpression(double.Parse(t.val, CultureInfo.InvariantCulture), t.line, t.col);
                break;
            }

            case 3: {
                Get();
                result = new NumberExpression(int.Parse(t.val), t.line, t.col);
                break;
            }

            case 4: {
                Get();
                result = new StringLiteralExpression(t.val, t.line, t.col);
                break;
            }

            case 13: {
                Get();
                result = new NamedConstantExpression("TRUE", t.line, t.col);
                break;
            }

            case 38: {
                Get();
                result = new NamedConstantExpression("FALSE", t.line, t.col);
                break;
            }

            case 12: {
                Get();
                result = new NamedConstantExpression("NULL", t.line, t.col);
                break;
            }

            default: SynErr(45); break;
            }
            expression = result.Simplify();
        }
Exemple #3
0
        public FormattableString TryGetFriendlyMessage(FailedAssertion assertion)
        {
            var methodCallExpression = (MethodCallExpression)assertion.Expression;

            var collectionExpression = ExpressionHelper.GetInstanceOfMethodCall(methodCallExpression);

            var filter = (LambdaExpression)methodCallExpression.Arguments[1];

            var collection = ((IEnumerable)ExpressionHelper.EvaluateExpression(collectionExpression) !).Cast <object>();

            var compiledFilter = filter.Compile(true);

            var invalidMatches = new List <object>();

            var moreItems    = false;
            var invalidCount = 0;

            var subMessages = new List <FormattableString>();

            var index = 0;

            foreach (var obj in collection)
            {
                var isMatch = (bool)compiledFilter.DynamicInvoke(obj);

                if (!isMatch)
                {
                    invalidCount++;

                    if (invalidMatches.Count == 10)
                    {
                        moreItems = true;
                    }
                    else
                    {
                        invalidMatches.Add(obj);

                        var namedConstant = new NamedConstantExpression("item", obj);

                        var newExpression =
                            Expression.Lambda <Func <bool> >(
                                ExpressionHelper.ReplaceParameter(filter.Body, filter.Parameters[0], namedConstant));

                        var analyzer = new AssertionFailureAnalyzer(new AssertionFailureContext(new Assertion(newExpression, null, null), null));

                        var failures = analyzer.AnalyzeAssertionFailures();

                        foreach (var failure in failures)
                        {
                            if (failure.Message != null)
                            {
                                subMessages.Add(collectionExpression is MethodCallExpression
                  ? $"[{index}] - {failure.Message}"
                  : (FormattableString)$"{collectionExpression}[{index}] - {failure.Message}");
                            }
                        }
                    }
                }

                index++;
            }

            FormattableString MessagesPerItem()
            {
                return(subMessages.Count switch
                {
                    0 => $"",
                    1 when invalidCount == 1 => $@"

{subMessages[0]}",
                    _ => $@"

Messages per item:

{subMessages}"
                });
            }
Exemple #4
0
        private void AnnotateExpressionTree(OqlExpression expressionTree)
        {
            foreach (ParameterExpression parExp in expressionTree.GetAll(e => e is ParameterExpression).ToList())
            {
                if (Guid.Empty.Equals(parExp.ParameterValue) || DateTime.MinValue.Equals(parExp.ParameterValue))
                {
                    var parent = parExp.Parent;
                    if (parent.Operator == "=")
                    {
                        var i       = parent.Children.IndexOf(parExp);
                        var nullExp = new NamedConstantExpression("NULL", false, 0, 0);
                        parent.Children[i] = nullExp;
                        ((IManageExpression)nullExp).SetParent(parent);
                        parent.Operator = "IS";
                    }
                    if (parent.Operator == "<>")
                    {
                        var i       = parent.Children.IndexOf(parExp);
                        var nullExp = new NamedConstantExpression("NULL", true, 0, 0);
                        parent.Children[i] = nullExp;
                        ((IManageExpression)nullExp).SetParent(parent);
                        parent.Operator = "IS";
                    }
                }
            }

            foreach (IdentifierExpression exp in expressionTree.GetAll(e => e is IdentifierExpression).ToList())
            {
                string[] arr       = ((string)exp.Value).Split('.');
                string   fieldName = arr[arr.Length - 1];               // In case of embedded or value types this will be overwritten
                Relation relation;
                Class    parentClass = GetParentClass(exp, arr, out fieldName, out relation);

                if (fieldName == "oid")
                {
                    string[] oidColumns = (from c in parentClass.Oid.OidColumns select QualifiedColumnName.Get(c)).ToArray();
                    if (relation != null)
                    {
                        // In these cases we don't need the join to the table of the class owning the oid.
                        // It's sufficient to compare against the foreign keys stored in the owner class' table
                        // or in the mapping table
                        if (relation.MappingTable != null)
                        {
                            oidColumns = (from c in relation.MappingTable.ChildForeignKeyColumns select QualifiedColumnName.Get(relation.MappingTable, c)).ToArray();
                        }
                        else if (relation.Multiplicity == RelationMultiplicity.Element)
                        {
                            oidColumns = (from c in relation.ForeignKeyColumns select QualifiedColumnName.Get(c)).ToArray();
                        }
                    }

                    ParameterExpression parExp   = exp.Siblings[0] as ParameterExpression;
                    var isDirectSingleExpression = exp.Parent.Operator != "=" || oidColumns.Length == 1 && exp.Siblings[0] is ConstantExpression;                     // like "oid = 123"
                    if (parExp == null && !isDirectSingleExpression)
                    {
                        throw new QueryException(10010, $"Expression '{exp.ToString()}' resolves to an oid. It's sibling expression must be a ParameterExpression. But the sibling is {exp.Siblings[0]}");
                    }

                    object[] oidKeys = null;

                    if (!isDirectSingleExpression)
                    {
                        // split the ObjectId or an array into individual parameters
                        oidKeys = ExtractOidKeys(parExp);

                        // Now set the parameter value of the first column
                        if (oidKeys != null)
                        {
                            parExp.ParameterValue = oidKeys[0];
                        }
                    }

                    if (oidColumns.Length > 1 && exp.Children.Count == 0)
                    {
                        OqlExpression equalsExpression = exp.Parent;                          // Must be a = expression like 'xxx.oid = {0}'.
                        // We need some additional parameters for the additional columns.
                        MoveParameterExpression(expressionTree, parExp.Ordinal, oidColumns.Length - 1);

                        // Replace the parent expression with a new AND expression
                        OqlExpression andExpression = new OqlExpression(0, 0);
                        ((IManageExpression)andExpression).SetParent(equalsExpression.Parent);
                        equalsExpression.Parent.Children.Remove(equalsExpression);
                        equalsExpression.Parent.Add(andExpression);
                        // We need to set Parent and Child explicitly.
                        // See comment in IManageExpression.SetParent.
                        // Reuse the original equality expression as first child of the AND expression
                        ((IManageExpression)equalsExpression).SetParent(andExpression);
                        andExpression.Add(equalsExpression);
                        exp.SetAnnotation(anKey, oidColumns[0]);
                        int currentOrdinal = parExp.Ordinal;
                        // Now add the additional children of the AND expression
                        for (int i = 1; i < oidColumns.Length; i++)
                        {
                            OqlExpression newParent = equalsExpression.DeepClone;                             // equality expression and it's both children
                            andExpression.Add(newParent, "AND");
                            ((IManageExpression)newParent).SetParent(andExpression);
                            // Now patch the Annotation and a new parameter to the children
                            IdentifierExpression newIdentExp = (IdentifierExpression)newParent.Children.Where(e => e is IdentifierExpression).First();
                            newIdentExp.SetAnnotation(anKey, oidColumns[i]);
                            ParameterExpression newParExp = (ParameterExpression)newParent.Children.Where(e => e is ParameterExpression).First();
                            if (oidKeys != null)
                            {
                                newParExp.ParameterValue = oidKeys[i];
                            }
                            newParExp.Ordinal = ++currentOrdinal;
                        }
                    }
                    else
                    {
                        int index = 0;
                        if (exp.Children.Count > 0 && exp.Children[0] is IndexExpression)
                        {
                            index = (int)exp.Children[0].Value;
                        }
                        if (index >= oidColumns.Length)
                        {
                            throw new IndexOutOfRangeException("oid index exceeds oid column count");
                        }
                        exp.SetAnnotation(anKey, oidColumns[index]);
                    }
                }
                else
                {
                    Field field = parentClass.FindField(fieldName);
                    if (field != null)
                    {
                        exp.SetAnnotation(anKey, QualifiedColumnName.Get(field.Column));
                    }
                    else
                    {
                        Relation oneTooneRelation = parentClass.Relations.FirstOrDefault(r => r.Multiplicity == RelationMultiplicity.Element && (r.FieldName == fieldName || r.AccessorName == fieldName));
                        if (oneTooneRelation != null)
                        {
                            exp.SetAnnotation(anKey, QualifiedColumnName.Get(oneTooneRelation.ForeignKeyColumns.First()));
                        }

                        else
                        {
                            throw new Exception("Can't find Field mapping for " + fieldName + " in " + exp.Value);
                        }
                    }
                }
            }
        }