I cleaned up the code, and discovered many improvements along the way.
I do wish I could find a cleaner way to do this:
var whenMethodsFound = Observable.FromEventPattern<NotifyCollectionChangedEventHandler, NotifyCollectionChangedEventArgs> act => foundMethods.CollectionChanged += act, act => foundMethods.CollectionChanged -= act);
Idea:
Add a mapping extension in extension method class
Great for simple on the go, but manual for every class you want to do this with.
Which would look like this
public static IObservable<IEvent<PageEventArgs>> GetPublishingPageEvent(this DataFactory dataFactory) { return Observable.FromEvent((EventHandler<PageEventArgs> h) => new PageEventHandler(h), h => dataFactory.PublishingPage += h, h => dataFactory.PublishingPage -= h); }
public override ProblemCollection Check(TypeNode type) { Debug.WriteLine("Checking type:"+type.FullName); var initializer = type.Members.OfType<Method>( ).FirstOrDefault(x => x.FullName==type.FullName+".InitializeComponent"); if (initializer==null) return null; Debug.WriteLine(initializer.FullName); var constructorsWithNoInitCall = type.Members.OfType<Method>( ).Where(m => m.NodeType==NodeType.InstanceInitializer).ToList( ); var visitedMethods = new HashSet<string>( ); var foundMethods = new ObservableHashSet<Method>( ); var whenMethodsFound = Observable.FromEventPattern<NotifyCollectionChangedEventHandler, NotifyCollectionChangedEventArgs>(act => foundMethods.CollectionChanged += act,act => foundMethods.CollectionChanged -= act); whenMethodsFound.Where(e=>e.EventArgs.Action==NotifyCollectionChangedAction.Add).Select(x=>x.EventArgs) .Subscribe( e => { if (constructorsWithNoInitCall.Any( )) Parallel.ForEach(e.NewItems.Cast<Method>( ).Where(m => visitedMethods.Any(v => v==m.FullName)==false), i => { lock (visitedMethods) { if (visitedMethods.Contains(i.FullName)) return; visitedMethods.Add(i.FullName); } Debug.WriteLine("Visiting:"+i.FullName); var callers = (CallGraph.CallersFor(i)); constructorsWithNoInitCall.RemoveAll(x => callers.Any(c => x.FullName==c.FullName)); if (constructorsWithNoInitCall.Any( )) foreach (var item in callers.Where(c => visitedMethods.Any(v => v==c.FullName)==false)) { foundMethods.Add(item); } }); } ); foundMethods.Add(initializer); ReportProblem(constructorsWithNoInitCall, type); return Problems; }
No comments:
Post a Comment