/// <summary> /// A utility method to find and organize all the unbound parameters with Reactive entity types. /// </summary> /// <param name="expression">The expression to search for Reactive entities.</param> /// <returns>The Reactive entities in the expression, organized by entity type.</returns> public static ReactiveEntities Find(ExpressionSlim expression) { var impl = new Impl(); impl.Visit(expression); return(impl.Entities); }
/// <summary> /// Finds all the free variables in an expression. /// </summary> /// <param name="expression">The expression to visit.</param> /// <returns>The set of free variables.</returns> public static HashSet <ParameterExpressionSlim> Find(ExpressionSlim expression) { var impl = new Impl(); impl.Visit(expression); return(impl.Globals); }
/// <summary> /// Serializes an expression to Bonsai. /// </summary> /// <param name="expression">Expression to serialize.</param> /// <returns>Bonsai representation of the given expression.</returns> public Json.Expression Serialize(ExpressionSlim expression) { if (_mergeContext && _serializationState != null) { return(new SerializerImpl(_serializationState, _liftFactory).Visit(expression)); } else { var state = new SerializationState(_version); _serializationState = state; var body = new SerializerImpl(state, _liftFactory).Visit(expression); var context = state.ToJson(); _serializationState = null; // PERF: We could consider creating a specialized IDictionary for the // top-level JSON structure to avoid Dictionary allocation. return(Json.Expression.Object(new Dictionary <string, Json.Expression>(2) { { "Context", context }, { "Expression", body }, })); } }
/// <summary> /// Creates a new expression that is like this one, but using the supplied children. If all of the children are the same, it will return this expression. /// </summary> /// <param name="target">The <see cref="Target" /> property of the result.</param> /// <param name="defaultValue">The <see cref="DefaultValue" /> property of the result.</param> /// <returns>This expression if no children changed, or an expression with the updated children.</returns> public LabelExpressionSlim Update(LabelTargetSlim target, ExpressionSlim defaultValue) { if (target == Target && defaultValue == DefaultValue) { return(this); } return(new LabelExpressionSlim(target, defaultValue)); }
/// <summary> /// Method to reduce a slim expression to an expression. /// </summary> /// <param name="expression">The slim expression.</param> /// <returns>The expression represented by the slim expression.</returns> public virtual Expression Reduce(ExpressionSlim expression) { if (expression == null) { return(null); } return(expression.ToExpression()); // NB: Derived class can override to specify a factory. }
private static void Unpack(LambdaExpression expression, out Expression body, out IEnumerable <ParameterExpression> parameters) { var slimLambda = expression != null ? (LambdaExpressionSlim)expression.ToExpressionSlim() : null; ExpressionSlimTupletizer.Unpack(slimLambda, out var slimBody, out var slimParameters); var fatLambda = (LambdaExpression)ExpressionSlim.Lambda(slimBody, slimParameters).ToExpression(); body = fatLambda.Body; parameters = fatLambda.Parameters; }
private static TypeSlim Derive(ExpressionSlim expression) { var result = s_derivationVisitor.Visit(expression); if (result == null) { throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "Could not derive type of '{0}' for use as component in tuple.", expression)); } return(result); }
public void FreeVariableScannerSlim_Find_CatchBlock1() { var p1 = ExpressionSlim.Parameter(SlimType, "p1"); var slimExpr = ExpressionSlim.TryCatch(ExpressionSlim.Empty(), ExpressionSlim.Catch(SlimType, p1)); var free = FreeVariableScannerSlim.Find(slimExpr); Assert.AreEqual(1, free.Count); Assert.IsTrue(free.Contains(p1)); }
public void FreeVariableScannerSlim_Find_Lambda1() { var p1 = ExpressionSlim.Parameter(SlimType, "p1"); var slimExpr = ExpressionSlim.Lambda(p1); var free = FreeVariableScannerSlim.Find(slimExpr); Assert.AreEqual(1, free.Count); Assert.IsTrue(free.Contains(p1)); }
public void UnifyingSerializationHelpers_FindAndUnify_Subscription() { var metadata = new MetadataMock(); var uri = new Uri("test://id"); metadata.Subscriptions.Add(uri, new MockSubscription(uri)); var parameter = ExpressionSlim.Parameter(typeof(IAsyncReactiveQubscription).ToTypeSlim(), uri.ToCanonicalString()); var mappings = UnifyingSerializationHelpers.FindAndUnify(parameter, metadata); Assert.AreEqual(0, mappings.Count()); }
public void UnifyingSerializationHelpers_FindAndUnify_Parameterized() { var metadata = new MetadataMock(); var uri = new Uri("test://id"); metadata.Observables.Add(uri, new MockParameterizedObservable <int, int>(uri)); var parameter = ExpressionSlim.Parameter(typeof(Func <int, IAsyncReactiveQbservable <int> >).ToTypeSlim(), uri.ToCanonicalString()); var mappings = UnifyingSerializationHelpers.FindAndUnify(parameter, metadata); Assert.AreEqual(0, mappings.Count()); }
public void ExpressionSlimExtensions_ToExpressionSlim_Null() { #pragma warning disable IDE0034 // Simplify 'default' expression (illustrative of method signature) AssertEx.ThrowsException <ArgumentNullException>(() => ((Expression)null).ToExpressionSlim(), ex => Assert.AreEqual("expression", ex.ParamName)); AssertEx.ThrowsException <ArgumentNullException>(() => ((Expression)null).ToExpressionSlim(ExpressionSlimFactory.Instance), ex => Assert.AreEqual("expression", ex.ParamName)); AssertEx.ThrowsException <ArgumentNullException>(() => Expression.Constant(1).ToExpressionSlim(default(IExpressionSlimFactory)), ex => Assert.AreEqual("factory", ex.ParamName)); AssertEx.ThrowsException <ArgumentNullException>(() => ((ExpressionSlim)null).ToExpression(), ex => Assert.AreEqual("expression", ex.ParamName)); AssertEx.ThrowsException <ArgumentNullException>(() => ((ExpressionSlim)null).ToExpression(ExpressionFactory.Instance), ex => Assert.AreEqual("expression", ex.ParamName)); AssertEx.ThrowsException <ArgumentNullException>(() => ExpressionSlim.Default(typeof(int).ToTypeSlim()).ToExpression(default(IExpressionFactory)), ex => Assert.AreEqual("factory", ex.ParamName)); #pragma warning restore IDE0034 // Simplify 'default' expression }
public void ConstantExpressionSlim_ArgumentChecks() { var t = typeof(string).ToTypeSlim(); var v = ObjectSlim.Create(value: null, t, typeof(string)); AssertEx.ThrowsException <ArgumentNullException>(() => ExpressionSlim.Constant(value: null, t), ex => Assert.AreEqual("value", ex.ParamName)); AssertEx.ThrowsException <ArgumentNullException>(() => ExpressionSlim.Constant(v, type: null), ex => Assert.AreEqual("type", ex.ParamName)); AssertEx.ThrowsException <ArgumentNullException>(() => new ConstantExpressionSlim(value: null), ex => Assert.AreEqual("value", ex.ParamName)); AssertEx.ThrowsException <ArgumentNullException>(() => new TypedConstantExpressionSlim(value: null, t), ex => Assert.AreEqual("value", ex.ParamName)); AssertEx.ThrowsException <ArgumentNullException>(() => new TypedConstantExpressionSlim(v, type: null), ex => Assert.AreEqual("type", ex.ParamName)); }
public void FreeVariableScannerSlim_Find_Block2() { var p1 = ExpressionSlim.Parameter(SlimType, "p1"); var p2 = ExpressionSlim.Parameter(SlimType, "p2"); var slimExpr = ExpressionSlim.Block(new[] { p1 }, ExpressionSlim.Add(p1, p2)); var free = FreeVariableScannerSlim.Find(slimExpr); Assert.AreEqual(1, free.Count); Assert.IsTrue(free.Contains(p2)); }
public void UnifyingSerializationHelpers_FindAndUnify_MismatchProperty() { var metadata = new MetadataMock(); var uri = new Uri("test://id"); metadata.Observables.Add(uri, new MockObservable <TypeWithEnum>(uri)); var structuralType = StructuralTypeSlimReference.Create(hasValueEqualitySemantics: true, StructuralTypeSlimKind.Record); structuralType.AddProperty(structuralType.GetProperty("eg://enum", typeof(int).ToTypeSlim(), EmptyReadOnlyCollection <TypeSlim> .Instance, canWrite: true)); var observerableType = TypeSlim.Generic(((GenericDefinitionTypeSlim)typeof(IAsyncReactiveQbservable <>).ToTypeSlim()), new TypeSlim[] { structuralType }.ToReadOnly()); var parameter = ExpressionSlim.Parameter(observerableType, uri.ToCanonicalString()); Assert.ThrowsException <InvalidOperationException>(() => UnifyingSerializationHelpers.FindAndUnify(parameter, metadata)); }
/// <summary> /// Serializes an expression to Bonsai. /// </summary> /// <param name="expression">Expression to serialize.</param> /// <returns>Bonsai representation of the given expression.</returns> private Json.Expression JsonSerialize(ExpressionSlim expression) { var serializationState = new SerializationState(_version); var body = new SerializerImpl(serializationState, GetConstantSerializerDelegate).Visit(expression); var context = serializationState.ToJson(); // PERF: We could consider creating a specialized IDictionary for the // top-level JSON structure to avoid Dictionary allocation. return(Json.Expression.Object(new Dictionary <string, Json.Expression>(2) { { "Context", context }, { "Expression", body }, })); }
public void ExpressionSlimToExpressionConverter_Throw() { var ex = new Exception(); var conv = new ExpressionSlimToExpressionConverter(); { var t = ExpressionSlim.Throw(Expression.Constant(ex).ToExpressionSlim()); var e = conv.Visit(t); Assert.AreEqual(ExpressionType.Throw, e.NodeType); var u = (UnaryExpression)e; Assert.AreEqual(typeof(void), u.Type); Assert.AreEqual(ExpressionType.Constant, u.Operand.NodeType); var c = (ConstantExpression)u.Operand; Assert.AreSame(ex, c.Value); } { var t = ExpressionSlim.Throw(Expression.Constant(ex).ToExpressionSlim(), typeof(int).ToTypeSlim()); var e = conv.Visit(t); Assert.AreEqual(ExpressionType.Throw, e.NodeType); var u = (UnaryExpression)e; Assert.AreEqual(typeof(int), u.Type); Assert.AreEqual(ExpressionType.Constant, u.Operand.NodeType); var c = (ConstantExpression)u.Operand; Assert.AreSame(ex, c.Value); } { var t = ExpressionSlim.MakeUnary(ExpressionType.Throw, Expression.Constant(ex).ToExpressionSlim(), type: null); var e = conv.Visit(t); Assert.AreEqual(ExpressionType.Throw, e.NodeType); var u = (UnaryExpression)e; Assert.AreEqual(typeof(void), u.Type); Assert.AreEqual(ExpressionType.Constant, u.Operand.NodeType); var c = (ConstantExpression)u.Operand; Assert.AreSame(ex, c.Value); } }
public void ExpressionSlimToExpressionConverter_Constant_Null() { var objNull = ObjectSlim.Create(value: null, typeof(object).ToTypeSlim(), typeof(object)); var strNull = ObjectSlim.Create(value: null, typeof(string).ToTypeSlim(), typeof(string)); var n1 = ExpressionSlim.Constant(objNull); var n2 = ExpressionSlim.Constant(strNull, typeof(string).ToTypeSlim()); var c1 = (ConstantExpression)n1.ToExpression(); var c2 = (ConstantExpression)n2.ToExpression(); Assert.IsNull(c1.Value); Assert.AreEqual(typeof(object), c1.Type); Assert.IsNull(c2.Value); Assert.AreEqual(typeof(string), c2.Type); }
/// <summary> /// Reduces a slim expression to a Linq expression, first mapping slim /// types to types from the expanded definition of the free variables in /// the expression. /// </summary> /// <param name="expression">The expression to reduce.</param> /// <returns>The reduced expression.</returns> public override Expression Reduce(ExpressionSlim expression) { EnsureInvertedTypeSpace(); var freeVariables = FreeVariableScannerSlim.Find(expression); foreach (var free in freeVariables) { var unifications = FindAndUnify(free, _parent._metadata); foreach (var unification in unifications) { _invertedTypeSpace.MapType(unification.Key, unification.Value); } } return(base.Reduce(expression)); }
public static TypeSlim GetTypeSlim(this ExpressionSlim e) { var t = new TypeSlimDerivationVisitor().Visit(e); return(t); }
/// <summary> /// Method to serialize a slim representation of an expression. /// </summary> /// <param name="expression">The slim expression to serialize.</param> /// <returns>A string representing the expression.</returns> public virtual string Serialize(ExpressionSlim expression) { // PERF: Consider passing in a pooled string builder instance. return(JsonSerialize(expression).ToString()); }
/// <summary> /// Method to reduce a slim expression to an expression. /// </summary> /// <param name="expression">A slim expression.</param> /// <returns>The expression represented by the slim expression.</returns> public override Expression Reduce(ExpressionSlim expression) { return(Reducer.Visit(expression)); }
public override string Serialize(ExpressionSlim expression) { var substituted = new ExpressionSlimEntityTypeRecordizer().Apply(expression); return(base.Serialize(substituted)); }
private static void AssertToString(ExpressionSlim e, string s) { Assert.AreEqual(s, e.ToString()); }
public void ExpressionSlim_Update_Tests() { var boolSlim = new TypeToTypeSlimConverter().Visit(typeof(bool)); var intExpr1 = ExpressionSlim.Parameter(SlimType); var intExpr2 = ExpressionSlim.Parameter(SlimType); var intExpr3 = ExpressionSlim.Parameter(SlimType); var boolExpr1 = ExpressionSlim.Parameter(boolSlim); var boolExpr2 = ExpressionSlim.Parameter(boolSlim); var prop = SlimType.GetProperty("Foo", propertyType: null, EmptyReadOnlyCollection <TypeSlim> .Instance, canWrite: true); var elementInits = new ElementInitSlim[] { new ElementInitSlim(addMethod: null, arguments: null) }.ToReadOnly(); var method = SlimType.GetSimpleMethod("Foo", EmptyReadOnlyCollection <TypeSlim> .Instance, returnType: null); var b = ExpressionSlim.Add(intExpr1, intExpr2); Assert.AreNotSame(b, b.Update(intExpr1, conversion: null, intExpr3)); Assert.AreNotSame(b, b.Update(intExpr3, conversion: null, intExpr2)); var c = ExpressionSlim.Condition(boolExpr1, intExpr1, intExpr2); Assert.AreNotSame(c, c.Update(boolExpr2, intExpr1, intExpr2)); Assert.AreNotSame(c, c.Update(boolExpr1, intExpr2, intExpr3)); Assert.AreNotSame(c, c.Update(boolExpr1, intExpr1, intExpr3)); var i = ExpressionSlim.MakeIndex(intExpr1, prop, new ExpressionSlim[] { intExpr2 }.ToReadOnly()); Assert.AreNotSame(i, i.Update(intExpr2, new ExpressionSlim[] { intExpr2 }.ToReadOnly())); Assert.AreNotSame(i, i.Update(intExpr1, new ExpressionSlim[] { intExpr3 }.ToReadOnly())); var inv = ExpressionSlim.Invoke(intExpr1, new[] { intExpr2 }); Assert.AreNotSame(inv, inv.Update(intExpr2, new ExpressionSlim[] { intExpr2 }.ToReadOnly())); Assert.AreNotSame(inv, inv.Update(intExpr1, new ExpressionSlim[] { intExpr3 }.ToReadOnly())); var l = ExpressionSlim.Lambda(intExpr1); Assert.AreNotSame(l, l.Update(intExpr2, EmptyReadOnlyCollection <ParameterExpressionSlim> .Instance)); Assert.AreNotSame(l, l.Update(intExpr1, new ParameterExpressionSlim[] { ExpressionSlim.Parameter(SlimType) }.ToReadOnly())); var li = ExpressionSlim.ListInit(ExpressionSlim.New(SlimType)); Assert.AreNotSame(li, li.Update(ExpressionSlim.New(boolSlim), elementInits)); Assert.AreNotSame(li, li.Update(ExpressionSlim.New(SlimType), elementInits)); var ma = ExpressionSlim.Bind(prop, intExpr1); Assert.AreNotSame(ma, ma.Update(intExpr2)); var macc = ExpressionSlim.MakeMemberAccess(instance: null, prop); Assert.AreNotSame(macc, macc.Update(intExpr1)); var ml = ExpressionSlim.ListBind(prop); Assert.AreNotSame(ml, ml.Update(elementInits)); var mm = ExpressionSlim.MemberBind(prop); Assert.AreNotSame(mm, mm.Update(new MemberBindingSlim[] { ExpressionSlim.Bind(prop, intExpr1) }.ToReadOnly())); var m = ExpressionSlim.Call(method); Assert.AreNotSame(m, m.Update(intExpr1, new ExpressionSlim[] { intExpr2 }.ToReadOnly())); Assert.AreNotSame(m, m.Update(@object: null, new ExpressionSlim[] { intExpr2 }.ToReadOnly())); var na = ExpressionSlim.NewArrayInit(SlimType); Assert.AreNotSame(na, na.Update(new ExpressionSlim[] { intExpr1 }.ToReadOnly())); var nb = ExpressionSlim.NewArrayBounds(SlimType, intExpr1); Assert.AreNotSame(nb, nb.Update(new ExpressionSlim[] { intExpr2 }.ToReadOnly())); var ctor = SlimType.GetConstructor(new TypeSlim[] { SlimType }.ToReadOnly()); var n = ExpressionSlim.New(ctor, ExpressionSlim.Parameter(SlimType)); Assert.AreNotSame(n, n.Update(new ExpressionSlim[] { ExpressionSlim.Default(SlimType) }.ToReadOnly())); var t = ExpressionSlim.TypeIs(intExpr1, SlimType); Assert.AreNotSame(t, t.Update(intExpr2)); var u = ExpressionSlim.Not(boolExpr1); Assert.AreNotSame(u, u.Update(boolExpr2)); }
public void ExpressionSlim_ToString_Constant() { AssertToString(ExpressionSlim.Constant(ObjectSlim.Create(value: null, typeof(string).ToTypeSlim(), typeof(string)), typeof(string).ToTypeSlim()), "Constant(null, System.String)"); AssertToString(Expression.Constant(value: null, typeof(string)).ToExpressionSlim(), "Constant(null, System.String)"); AssertToString(Expression.Constant("bar", typeof(string)).ToExpressionSlim(), "Constant(bar, System.String)"); }
/// <summary> /// Creates a new expression that is like this one, but using the supplied children. If all of the children are the same, it will return this expression. /// </summary> /// <param name="breakLabel">The <see cref="BreakLabel" /> property of the result.</param> /// <param name="continueLabel">The <see cref="ContinueLabel" /> property of the result.</param> /// <param name="body">The <see cref="Body" /> property of the result.</param> /// <returns>This expression if no children changed, or an expression with the updated children.</returns> public LoopExpressionSlim Update(LabelTargetSlim breakLabel, LabelTargetSlim continueLabel, ExpressionSlim body) { if (breakLabel == BreakLabel && continueLabel == ContinueLabel && body == Body) { return(this); } return(new LoopExpressionSlim(body, breakLabel, continueLabel)); }
internal LoopExpressionSlim(ExpressionSlim body, LabelTargetSlim @break, LabelTargetSlim @continue) { Body = body; BreakLabel = @break; ContinueLabel = @continue; }
public void ListArgumentProvider_All() { var s = typeof(string).ToTypeSlim(); var i = typeof(int).ToTypeSlim(); var m = s.GetSimpleMethod("Substring", new ReadOnlyCollection <TypeSlim>(new[] { i, i }), s); var a0 = ExpressionSlim.Default(i); var a1 = ExpressionSlim.Default(i); var d = ExpressionSlim.Default(i); var c = ExpressionSlim.Call(m, a0, a1); var argProvider = new ListArgumentProviderSlim(c, a0); Assert.ThrowsException <NotSupportedException>(() => argProvider[0] = a0); Assert.ThrowsException <NotSupportedException>(() => argProvider.Add(a0)); Assert.ThrowsException <NotSupportedException>(() => argProvider.Clear()); Assert.ThrowsException <NotSupportedException>(() => argProvider.Insert(0, a0)); Assert.ThrowsException <NotSupportedException>(() => argProvider.Remove(a0)); Assert.ThrowsException <NotSupportedException>(() => argProvider.RemoveAt(0)); Assert.ThrowsException <ArgumentOutOfRangeException>(() => argProvider[-1]); Assert.ThrowsException <ArgumentOutOfRangeException>(() => argProvider[2]); Assert.AreSame(a0, argProvider[0]); Assert.AreSame(a1, argProvider[1]); Assert.AreEqual(2, argProvider.Count); Assert.IsTrue(argProvider.IsReadOnly); Assert.IsTrue(argProvider.Contains(a0)); Assert.IsTrue(argProvider.Contains(a1)); Assert.IsFalse(argProvider.Contains(d)); Assert.AreEqual(0, argProvider.IndexOf(a0)); Assert.AreEqual(1, argProvider.IndexOf(a1)); Assert.IsTrue(argProvider.IndexOf(d) < 0); var arr = new ExpressionSlim[5]; argProvider.CopyTo(arr, 2); Assert.IsNull(arr[0]); Assert.IsNull(arr[1]); Assert.AreSame(a0, arr[2]); Assert.AreSame(a1, arr[3]); Assert.IsNull(arr[4]); var e1 = argProvider.GetEnumerator(); Assert.IsTrue(e1.MoveNext()); Assert.AreSame(a0, e1.Current); Assert.IsTrue(e1.MoveNext()); Assert.AreSame(a1, e1.Current); Assert.IsFalse(e1.MoveNext()); var e2 = ((IEnumerable)argProvider).GetEnumerator(); Assert.IsTrue(e2.MoveNext()); Assert.AreSame(a0, e2.Current); Assert.IsTrue(e2.MoveNext()); Assert.AreSame(a1, e2.Current); Assert.IsFalse(e2.MoveNext()); }
internal LabelExpressionSlim(LabelTargetSlim label, ExpressionSlim defaultValue) { Target = label; DefaultValue = defaultValue; }