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); } } }
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(); }
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}" }); }
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); } } } } }