Tx/Source/Tx.LinqPad/ParserRegistry.cs

145 строки
5.0 KiB
C#

// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
using Microsoft.SqlServer.XEvent;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reactive;
using System.Reflection;
using System.Text;
namespace Tx.LinqPad
{
internal class ParserRegistry
{
private readonly MethodInfo[] _addFiles;
private readonly MethodInfo[] _addSessions;
public ParserRegistry()
{
string dir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
IEnumerable<Type> types = from file in Directory.GetFiles(dir, "Tx*.dll")
from t in Assembly.LoadFrom(file).GetTypes()
where t.IsPublic
select t;
IEnumerable<MethodInfo> methods = from t in types
from m in t.GetMethods()
where m.GetAttribute<FileParserAttribute>() != null
select m;
_addFiles = methods.ToArray();
methods = from t in types
from m in t.GetMethods()
where m.GetAttribute<RealTimeFeedAttribute>() != null
select m;
_addSessions = methods.ToArray();
}
public string Filter
{
get
{
FileParserAttribute[] attributes = (from mi in _addFiles
select mi.GetAttribute<FileParserAttribute>()).ToArray();
var sb = new StringBuilder("All Files|");
foreach (string ext in attributes.SelectMany(a => a.Extensions))
{
sb.Append('*');
sb.Append(ext);
sb.Append(';');
}
foreach (FileParserAttribute a in attributes)
{
sb.Append('|');
sb.Append(a.Description);
sb.Append('|');
foreach (string ext in a.Extensions)
{
sb.Append('*');
sb.Append(ext);
sb.Append(';');
}
}
return sb.ToString().Replace(";|", "|");
}
}
public IEnumerable<Assembly> GetAssemblies()
{
var assemblies = new List<Assembly>((from m in _addFiles select m.DeclaringType.Assembly).Distinct());
// HACK: putting this in ParserRegistry is ok for now
// But we need clear story of adding parsers withou changing the LINQPad driver core
assemblies.Add(typeof(CallStack).Assembly);
assemblies.Add(typeof(XEventAttribute).Assembly);
assemblies.Add(typeof(IXETarget).Assembly);
return assemblies;
}
public IEnumerable<string> GetNamespaces()
{
var namespaces = new List<string>((from m in _addFiles select m.DeclaringType.Namespace).Distinct());
namespaces.Add("Microsoft.SqlServer.XEvent");
return namespaces;
}
public Dictionary<Type, long> GetTypeStatistics(Type[] types, string[] files)
{
var stat = new TypeOccurenceStatistics(types);
AddFiles(stat, files);
stat.Run();
return stat.Statistics;
}
public void AddFiles(IPlaybackConfiguration playback, string[] files)
{
var filesByExtension = new Dictionary<string, List<string>>();
foreach (string f in files)
{
string extension = Path.GetExtension(f).ToLowerInvariant();
List<string> sameExtension;
if (!filesByExtension.TryGetValue(extension, out sameExtension))
{
sameExtension = new List<string>();
filesByExtension.Add(extension, sameExtension);
}
sameExtension.Add(f);
}
foreach (string ext in filesByExtension.Keys)
{
MethodInfo addMethod = (from mi in _addFiles
where mi.GetAttribute<FileParserAttribute>().Extensions.Contains(ext)
select mi).FirstOrDefault();
addMethod.Invoke(null, new object[] {playback, filesByExtension[ext].ToArray()});
}
}
public void AddSession(IPlaybackConfiguration playback, string session)
{
foreach (MethodInfo addMethod in _addSessions)
{
addMethod.Invoke(null, new object[] {playback, session});
}
}
private T GetAttribute<T>(ICustomAttributeProvider provider)
{
return (T) (provider.GetCustomAttributes(typeof (T), false))[0];
}
}
}