public void Analyze_ExpressionHasMultipleParametersWithReduntantAccessors_ReturnsMinimalPropertyAccessTree() { Expression <Func <Person, SimpleNotifyValue, int> > ageAdder = (person, simpleNotify) => person.Age + person.Age + simpleNotify.Value + simpleNotify.Value; var tree = ExpressionPropertyAnalyzer.Analyze(ageAdder); Assert.AreEqual(2, tree.Children.Count); ParameterNode personParameterNode = (ParameterNode)tree.Children[0]; Assert.AreEqual(1, personParameterNode.Children.Count); Assert.AreEqual("person", personParameterNode.Name); PropertyAccessNode personAgePropertyAccessNode = (PropertyAccessNode)personParameterNode.Children[0]; Assert.AreEqual(typeof(Person), personAgePropertyAccessNode.Property.DeclaringType); Assert.AreEqual("Age", personAgePropertyAccessNode.PropertyName); ParameterNode simpleNotifyParameterNode = (ParameterNode)tree.Children[1]; Assert.AreEqual(1, simpleNotifyParameterNode.Children.Count); Assert.AreEqual("simpleNotify", simpleNotifyParameterNode.Name); PropertyAccessNode simpleNotifyValuePropertyAccessNode = (PropertyAccessNode)simpleNotifyParameterNode.Children[0]; Assert.AreEqual(typeof(SimpleNotifyValue), simpleNotifyValuePropertyAccessNode.Property.DeclaringType); Assert.AreEqual("Value", simpleNotifyValuePropertyAccessNode.PropertyName); }
public DependsOnMethod <T> OnChanged <TResult>(Expression <Func <T, TResult> > propertyAccessor) { PropertyAccessTree propertyAccessTree = ExpressionPropertyAnalyzer.Analyze(propertyAccessor); if (propertyAccessTree.DoesEntireTreeSupportINotifyPropertyChanging) { if (_propertyChangeSubscribers == null) { _propertyChangeSubscribers = new List <IPropertyAccessTreeSubscriber <DependsOnMethod <T> > >(); } var subscriber = propertyAccessTree.CreateCallbackSubscription <DependsOnMethod <T> >(OnAnyPropertyInSubscriptionChanges); _propertyChangeSubscribers.Add(subscriber); } else { if (_accessTreesWithoutNotifyPropertyChanging == null) { _accessTreesWithoutNotifyPropertyChanging = new List <PropertyAccessTree>(); } _accessTreesWithoutNotifyPropertyChanging.Add(propertyAccessTree); } return(this); }
public void Analyze_ExpressionContainsNewOperatorWithMemberAssignmentInitialization_ReturnsPropertyAccessTree() { Expression <Func <Person, Person> > expression = person => new Person() { Name = person.Name, Age = person.Age }; var tree = ExpressionPropertyAnalyzer.Analyze(expression); Assert.AreEqual(1, tree.Children.Count); PropertyAccessTreeNode parameterNode = tree.Children[0]; Assert.IsInstanceOfType(typeof(ParameterNode), parameterNode); Assert.AreEqual(2, parameterNode.Children.Count); PropertyAccessNode ageNode = (PropertyAccessNode)parameterNode.Children[0]; Assert.AreEqual(_ageProperty, ageNode.Property); Assert.AreEqual(0, ageNode.Children.Count); PropertyAccessNode nameNode = (PropertyAccessNode)parameterNode.Children[1]; Assert.AreEqual(_nameProperty, nameNode.Property); Assert.AreEqual(0, nameNode.Children.Count); }
public void Analyze_ExpressionIncludesConstantImplementingINotifyPropertyChanged_TreeContainsTwoBranches() { Person localPersonAppearingAsConstantInExpression = new Person(); Expression <Func <Person, int> > expression = p => p.Age + localPersonAppearingAsConstantInExpression.Age; PropertyAccessTree tree = ExpressionPropertyAnalyzer.Analyze(expression); Assert.AreEqual(2, tree.Children.Count); PropertyAccessTreeNode parameterNode = tree.Children[0]; Assert.IsInstanceOfType(typeof(ParameterNode), parameterNode); Assert.AreEqual(1, parameterNode.Children.Count); PropertyAccessNode parameterAgeNode = (PropertyAccessNode)parameterNode.Children[0]; Assert.AreEqual(_ageProperty, parameterAgeNode.Property); Assert.AreEqual(0, parameterAgeNode.Children.Count); PropertyAccessTreeNode constantNode = tree.Children[1]; Assert.IsInstanceOfType(typeof(ConstantNode), constantNode); Assert.AreEqual(localPersonAppearingAsConstantInExpression, ((ConstantNode)constantNode).Value); Assert.AreEqual(1, constantNode.Children.Count); PropertyAccessNode constantAgeNode = (PropertyAccessNode)constantNode.Children[0]; Assert.AreEqual(_ageProperty, constantAgeNode.Property); Assert.AreEqual(0, constantAgeNode.Children.Count); }
public void Analyze_ConditionalExpressionBothOneLevelAndTwoLevelProperties_TreeCorrect() { Expression <Func <Person, int> > expression = p => p.Age > 3 ? p.Age : p.Brother.Age; PropertyAccessTree tree = ExpressionPropertyAnalyzer.Analyze(expression); Assert.AreEqual(1, tree.Children.Count); PropertyAccessTreeNode parameterNode = tree.Children[0]; Assert.AreEqual(2, parameterNode.Children.Count); PropertyAccessNode firstLevelAgeNode = (PropertyAccessNode)parameterNode.Children[1]; Assert.AreEqual(_ageProperty, firstLevelAgeNode.Property); Assert.AreEqual(0, firstLevelAgeNode.Children.Count); PropertyAccessNode brotherNode = (PropertyAccessNode)parameterNode.Children[0]; Assert.AreEqual(_brotherProperty, brotherNode.Property); Assert.AreEqual(1, brotherNode.Children.Count); PropertyAccessNode secondLevelAgeNode = (PropertyAccessNode)brotherNode.Children[0]; Assert.AreEqual(_ageProperty, secondLevelAgeNode.Property); Assert.AreEqual(0, secondLevelAgeNode.Children.Count); }
public void Analyze_ExpressionContainsNothingWithINotifyPropertyChanged_ReturnsNull() { Expression <Func <int, bool> > expression = i => i == 0; PropertyAccessTree tree = ExpressionPropertyAnalyzer.Analyze(expression); Assert.IsNull(tree); }
public void Analyze_SpecialTypeFilterWithExpressionThatFailsFilter_ReturnsPropertyAccessTree() { Expression <Func <string, bool> > expression = str => str.Length == 0; PropertyAccessTree tree = ExpressionPropertyAnalyzer.Analyze(expression, type => type == typeof(int)); Assert.IsNull(tree); }
public void Analyze_ExpressionAccessesOnlyParameter_TreeHasOnlyParameter() { Expression <Func <Person, Person> > expression = p => p; PropertyAccessTree tree = ExpressionPropertyAnalyzer.Analyze(expression); Assert.AreEqual(1, tree.Children.Count); Assert.IsInstanceOfType(typeof(ParameterNode), tree.Children[0]); }
public void Analyze_ExpressionAccessesOnlyParameter_TreeHasOnlyParameter() { Expression <Func <Person, Person> > expression = p => p; PropertyAccessTree tree = ExpressionPropertyAnalyzer.Analyze(expression); Assert.AreEqual(1, tree.Children.Count); tree.Children[0].Should().BeOfType <ParameterNode>(); }
public void Analyze_ExpressionContainsDelegate_ReturnsPropertyAccessTree() { Func <Person, string> del = person => person.Name; Expression <Func <Person, string> > expression = person => del(person); var tree = ExpressionPropertyAnalyzer.Analyze(expression); Assert.AreEqual(1, tree.Children.Count); PropertyAccessTreeNode parameterNode = tree.Children[0]; Assert.IsInstanceOfType(typeof(ParameterNode), parameterNode); Assert.AreEqual(0, parameterNode.Children.Count); }
public void Analyze_ExpressionReturnsOneLevelProperty_TreeHasOneParameterBranchWithOneProperty() { Expression <Func <Person, int> > expression = p => p.Age; PropertyAccessTree tree = ExpressionPropertyAnalyzer.Analyze(expression); Assert.AreEqual(1, tree.Children.Count); PropertyAccessTreeNode parameterNode = tree.Children[0]; Assert.AreEqual(1, parameterNode.Children.Count); PropertyAccessNode propertyNode = (PropertyAccessNode)parameterNode.Children[0]; Assert.AreEqual(_ageProperty, propertyNode.Property); Assert.AreEqual(0, propertyNode.Children.Count); }
public void Analyze_ExpressionUsesMethodCallOnOneLevelProperty_TreeHasOneParameterBranchWithOneProperty() { Expression <Func <Person, bool> > expression = p => string.IsNullOrEmpty(p.Name); PropertyAccessTree tree = ExpressionPropertyAnalyzer.Analyze(expression); Assert.AreEqual(1, tree.Children.Count); PropertyAccessTreeNode parameterNode = tree.Children[0]; Assert.AreEqual(1, parameterNode.Children.Count); PropertyAccessNode propertyNode = (PropertyAccessNode)parameterNode.Children[0]; Assert.AreEqual(_nameProperty, propertyNode.Property); Assert.AreEqual(0, propertyNode.Children.Count); }
public void Analyze_TwoLevelPropertyWhereSubPropertyIsNotINotifyPropertyChanged_TreeContainsFirstProperty() { Expression <Func <Person, bool> > expression = p => p.Name.Length == 0; PropertyAccessTree tree = ExpressionPropertyAnalyzer.Analyze(expression); Assert.AreEqual(1, tree.Children.Count); PropertyAccessTreeNode parameterNode = tree.Children[0]; Assert.IsInstanceOfType(typeof(ParameterNode), parameterNode); Assert.AreEqual(1, parameterNode.Children.Count); PropertyAccessNode nameNode = (PropertyAccessNode)parameterNode.Children[0]; Assert.AreEqual(_nameProperty, nameNode.Property); Assert.AreEqual(0, nameNode.Children.Count); }
public SortingReadOnlyContinuousCollection(IList <TSource> list, Expression <Func <TSource, TKey> > keySelectorExpression, bool descending) : base(list, ExpressionPropertyAnalyzer.Analyze(keySelectorExpression)) { this.KeySelector = keySelectorExpression.CachedCompile(); this.KeySorter = new SortsSourceByKey <TSource, TKey>(this.KeySelector, descending); SetComparerChain(this.KeySorter); BuildItemsInSortOrder(this.Source); this.NotifyCollectionChangedMonitor.Add += OnAdd; this.NotifyCollectionChangedMonitor.Remove += OnRemove; this.NotifyCollectionChangedMonitor.Reset += OnReset; this.NotifyCollectionChangedMonitor.Replace += OnReplace; this.NotifyCollectionChangedMonitor.ItemChanged += OnItemChanged; }
public void Analyze_SpecialTypeFilterWithExpressionThatPassesFilter_ReturnsPropertyAccessTree() { Expression <Func <string, bool> > expression = str => str.Length == 0; PropertyAccessTree tree = ExpressionPropertyAnalyzer.Analyze(expression, type => type == typeof(string)); Assert.AreEqual(1, tree.Children.Count); PropertyAccessTreeNode parameterNode = tree.Children[0]; Assert.IsInstanceOfType(typeof(ParameterNode), parameterNode); Assert.AreEqual(1, parameterNode.Children.Count); PropertyAccessNode lengthNode = (PropertyAccessNode)parameterNode.Children[0]; Assert.AreEqual(typeof(string).GetProperty("Length"), lengthNode.Property); Assert.AreEqual(0, lengthNode.Children.Count); }
public void Analyze_ExpressionContainsDelegateAndPropertyAccess_ReturnsPropertyAccessTree() { Expression <Func <Person, string> > expression = person => this.StringPassThrough(person.Name); var tree = ExpressionPropertyAnalyzer.Analyze(expression); Assert.AreEqual(2, tree.Children.Count); PropertyAccessTreeNode parameterNode = tree.Children[0]; Assert.IsInstanceOfType(typeof(ParameterNode), parameterNode); Assert.AreEqual(1, parameterNode.Children.Count); PropertyAccessTreeNode constantNode = tree.Children[1]; Assert.IsInstanceOfType(typeof(ConstantNode), constantNode); Assert.AreEqual(1, constantNode.Children.Count); }
public void Analyze_ExpressionContainsThis_TreeContainsOneBranch() { Expression <Func <Person, int> > expression = p => this.TestProperty; PropertyAccessTree tree = ExpressionPropertyAnalyzer.Analyze(expression); Assert.AreEqual(2, tree.Children.Count); PropertyAccessTreeNode constantNode = tree.Children[1]; Assert.IsInstanceOfType(typeof(ConstantNode), constantNode); Assert.AreEqual(this, ((ConstantNode)constantNode).Value); Assert.AreEqual(1, constantNode.Children.Count); PropertyAccessNode testPropertyNode = (PropertyAccessNode)constantNode.Children[0]; Assert.AreEqual(GetType().GetProperty("TestProperty"), testPropertyNode.Property); Assert.AreEqual(0, testPropertyNode.Children.Count); }
public SelectManyReadOnlyContinuousCollection( IList <TSource> list, Expression <Func <TSource, IList <TResult> > > manySelector) : base(list, ExpressionPropertyAnalyzer.Analyze(manySelector)) { _sourceToCollectionNode = new Dictionary <TSource, List <IndexingSkipList <IList <TResult> > .Node> >(); _collectionToNode = new Dictionary <IList <TResult>, List <IndexingSkipList <IList <TResult> > .Node> >(); _weakEventHandlers = new Dictionary <IList <TResult>, WeakEventHandler>(); _collectionIndex = new IndexingSkipList <IList <TResult> >(); _selectorFunction = manySelector.CachedCompile(); RecordCurrentValues(_collectionIndex.TopLeft, this.Source); this.NotifyCollectionChangedMonitor.Add += OnAdd; this.NotifyCollectionChangedMonitor.Remove += OnRemove; this.NotifyCollectionChangedMonitor.Reset += OnReset; this.NotifyCollectionChangedMonitor.Move += OnMove; this.NotifyCollectionChangedMonitor.Replace += OnReplace; this.NotifyCollectionChangedMonitor.ItemChanged += OnItemChanged; }
internal GroupingReadOnlyContinuousCollection( IList <TSource> list, Expression <Func <TSource, TKey> > keySelectorExpression) : base(list, ExpressionPropertyAnalyzer.Analyze(keySelectorExpression)) { this.KeySelector = keySelectorExpression.CachedCompile(); this.Output = new ContinuousCollection <GroupedReadOnlyContinuousCollection <TKey, TSource> >(); this.ItemToGroupIndex = new Dictionary <TSource, GroupedReadOnlyContinuousCollection <TKey, TSource> >(); AddNewItems(this.Source); this.NotifyCollectionChangedMonitor.Add += OnAdd; this.NotifyCollectionChangedMonitor.Remove += OnRemove; this.NotifyCollectionChangedMonitor.Reset += OnReset; this.NotifyCollectionChangedMonitor.Replace += OnReplace; this.NotifyCollectionChangedMonitor.ItemChanged += OnItemChanged; this.Output.CollectionChanged += OnOutputCollectionChanged; }
public FilteringReadOnlyContinuousCollection(IList <TSource> list, Expression <Func <TSource, bool> > expression) : base(list, ExpressionPropertyAnalyzer.Analyze(expression)) { #if DEBUG this.Expr = expression; #endif this.FilterFunction = expression.CachedCompile(); this.Output = new ContinuousCollection <TSource>(); this.ItemLookup = new HashSet <TSource>(); this.Output.CollectionChanged += RefireCollectionChangedFromOutput; AddNewItems(this.Source); this.NotifyCollectionChangedMonitor.Add += OnAdd; this.NotifyCollectionChangedMonitor.Remove += OnRemove; this.NotifyCollectionChangedMonitor.Reset += OnReset; this.NotifyCollectionChangedMonitor.Replace += OnReplace; this.NotifyCollectionChangedMonitor.ItemChanged += OnItemChanged; }
public void Analyze_ExpressionReturnsTwoLevelProperty_TreeHasOneParameterBranchWithTwoProperties() { Expression <Func <Person, int> > expression = p => p.Brother.Age; PropertyAccessTree tree = ExpressionPropertyAnalyzer.Analyze(expression); Assert.AreEqual(1, tree.Children.Count); PropertyAccessTreeNode parameterNode = tree.Children[0]; Assert.AreEqual(1, parameterNode.Children.Count); PropertyAccessNode brotherNode = (PropertyAccessNode)parameterNode.Children[0]; Assert.AreEqual(_brotherProperty, brotherNode.Property); Assert.AreEqual(1, brotherNode.Children.Count); PropertyAccessNode ageNode = (PropertyAccessNode)brotherNode.Children[0]; Assert.AreEqual(_ageProperty, ageNode.Property); Assert.AreEqual(0, ageNode.Children.Count); }
public void Analyze_ConditionalExpressionReferencingTwoProperties_TreeContainsOnePropertyBranchWithBothProperties() { Expression <Func <Person, int> > expression = p => string.IsNullOrEmpty(p.Name) ? p.Age : 0; PropertyAccessTree tree = ExpressionPropertyAnalyzer.Analyze(expression); Assert.AreEqual(1, tree.Children.Count); PropertyAccessTreeNode parameterNode = tree.Children[0]; Assert.AreEqual(2, parameterNode.Children.Count); PropertyAccessNode ageNode = (PropertyAccessNode)parameterNode.Children[0]; Assert.AreEqual(_ageProperty, ageNode.Property); Assert.AreEqual(0, ageNode.Children.Count); PropertyAccessNode nameNode = (PropertyAccessNode)parameterNode.Children[1]; Assert.AreEqual(_nameProperty, nameNode.Property); Assert.AreEqual(0, nameNode.Children.Count); }
public void Analyze_ExpressionContainsNewOperatorWithConstructorArguments_ReturnsPropertyAccessTree() { Expression <Func <Person, Person> > expression = person => new Person(person.Name, person.Age); var tree = ExpressionPropertyAnalyzer.Analyze(expression); Assert.AreEqual(1, tree.Children.Count); PropertyAccessTreeNode parameterNode = tree.Children[0]; parameterNode.Should().BeOfType <ParameterNode>(); Assert.AreEqual(2, parameterNode.Children.Count); PropertyAccessNode ageNode = (PropertyAccessNode)parameterNode.Children[0]; Assert.AreEqual(_ageProperty, ageNode.Property); Assert.AreEqual(0, ageNode.Children.Count); PropertyAccessNode nameNode = (PropertyAccessNode)parameterNode.Children[1]; Assert.AreEqual(_nameProperty, nameNode.Property); Assert.AreEqual(0, nameNode.Children.Count); }
protected void Register <TResult>(Expression <Func <T, TResult> > propertyAccessor, FireOn fireOn) { PropertyAccessTree propertyAccessTree = ExpressionPropertyAnalyzer.Analyze(propertyAccessor); if (propertyAccessTree.DoesEntireTreeSupportINotifyPropertyChanging) { if (_propertyChangeSubscribers == null) { _propertyChangeSubscribers = new List <IPropertyAccessTreeSubscriber <ReactiveMethod <T> > >(); } Action <ReactiveMethod <T>, object, PropertyChangingEventArgs> onPropertyChanging = OnAnyPropertyInSubscriptionChanging; Action <ReactiveMethod <T>, object, PropertyChangedEventArgs> onPropertyChanged = OnAnyPropertyInSubscriptionChanged; if ((fireOn & FireOn.PropertyChanging) != FireOn.PropertyChanging) { onPropertyChanging = null; } if ((fireOn & FireOn.PropertyChanged) != FireOn.PropertyChanged) { onPropertyChanged = null; } var subscriber = propertyAccessTree.CreateCallbackSubscription <ReactiveMethod <T> >( onPropertyChanging, onPropertyChanged ); _propertyChangeSubscribers.Add(subscriber); } else if ((fireOn & FireOn.PropertyChanged) == FireOn.PropertyChanged) { if (_accessTreesWithoutNotifyPropertyChanging == null) { _accessTreesWithoutNotifyPropertyChanging = new List <PropertyAccessTree>(); } _accessTreesWithoutNotifyPropertyChanging.Add(propertyAccessTree); } }
public GroupJoinReadOnlyContinuousCollection( IList <TOuter> outer, IList <TInner> inner, Expression <Func <TOuter, TKey> > outerKeySelector, Expression <Func <TInner, TKey> > innerKeySelector, Expression <Func <TOuter, ReadOnlyContinuousCollection <TInner>, TResult> > resultSelector) { _outer = outer; _inner = inner; _outerKeySelector = outerKeySelector.CachedCompile(); _innerKeySelector = innerKeySelector.CachedCompile(); _resultSelector = resultSelector.CachedCompile(); _keyToOuterLookup = new Dictionary <TKey, List <OuterEntry> >(_outer.Count); _outerEntries = new Dictionary <TOuter, OuterEntry>(_outer.Count); _keyToInnerLookup = new Dictionary <TKey, List <TInner> >(_inner.Count); _innerEntries = new Dictionary <TInner, InnerEntry>(); _outerReferenceTracker = new ReferenceCountTracker <TOuter>(outer); RebuildAll(); _outerNotifyCollectionChangedMonitor = new NotifyCollectionChangedMonitor <TOuter>(ExpressionPropertyAnalyzer.Analyze(outerKeySelector), outer); _outerNotifyCollectionChangedMonitor.Add += OnOuterAdd; _outerNotifyCollectionChangedMonitor.Remove += OnOuterRemove; _outerNotifyCollectionChangedMonitor.Reset += OnOuterReset; _outerNotifyCollectionChangedMonitor.Move += OnOuterMove; _outerNotifyCollectionChangedMonitor.Replace += OnOuterItemReplace; _outerNotifyCollectionChangedMonitor.ItemChanged += OnOuterKeyChanged; _innerNotifyCollectionChangedMonitor = new NotifyCollectionChangedMonitor <TInner>(ExpressionPropertyAnalyzer.Analyze(innerKeySelector), inner); _innerNotifyCollectionChangedMonitor.Add += OnInnerAdd; _innerNotifyCollectionChangedMonitor.Remove += OnInnerRemove; _innerNotifyCollectionChangedMonitor.Reset += OnInnerReset; _innerNotifyCollectionChangedMonitor.Move += OnInnerMove; _innerNotifyCollectionChangedMonitor.Replace += OnInnerItemReplace; _innerNotifyCollectionChangedMonitor.ItemChanged += OnInnerItemChanged; }