xamarin-macios/tests/xtro-sharpie/Runner.cs

211 строки
4.8 KiB
C#
Исходник Обычный вид История

2016-05-26 16:06:52 +03:00
using System;
using System.Collections.Generic;
using System.IO;
2016-08-18 03:11:05 +03:00
using System.Linq;
2016-05-26 16:06:52 +03:00
using Mono.Cecil;
using Clang.Ast;
namespace Extrospection {
public class Runner {
public Runner ()
{
}
public void Execute (string pchFile, IEnumerable<string> assemblyNames)
{
var managed_reader = new AssemblyReader () {
new DesignatedInitializerCheck (),
new DllImportCheck (),
new EnumCheck (),
new FieldCheck (), // very noisy now, some stuff are still manually bound / harder to detect
new ObjCInterfaceCheck (),
new ObjCProtocolCheck (),
new SelectorCheck (),
// new ListNative (), // for debug
};
foreach (var assemblyName in assemblyNames) {
var name = Path.GetFileNameWithoutExtension (assemblyName);
if (name.EndsWith (".iOS", StringComparison.Ordinal))
Helpers.Platform = "ios";
else if (name.EndsWith (".Mac", StringComparison.Ordinal))
Helpers.Platform = "osx";
else if (name.EndsWith (".WatchOS", StringComparison.Ordinal))
Helpers.Platform = "watchos";
else if (name.EndsWith (".TVOS", StringComparison.Ordinal))
Helpers.Platform = "tvos";
managed_reader.Load (assemblyName);
}
var reader = new AstReader ();
2016-08-18 03:11:05 +03:00
foreach (var v in managed_reader) {
reader.TranslationUnitParsed += tu => {
tu.DeclFilter = ModuleExclusionList.DeclFilter;
tu.Accept (v);
};
}
2016-05-26 16:06:52 +03:00
reader.Load (pchFile);
managed_reader.End ();
}
}
2016-08-18 03:11:05 +03:00
class ModuleExclusionList {
static List<string> macOSXExclusionList = new List<string> () {
// Nice to have someday
"IOBluetooth", "IOBluetoothUI", "PubSub", "CryptoTokenKit", "DiscRecording", "DiscRecordingUI", "ImageCaptureCore", "OSAKit", "AudioVideoBridging", "Automator", "ImageCapture",
// Maybe?
"ICADevices", "OpenDirectory", "IMServicePlugIn", "PreferencePanes", "ScreenSaver",
// Nope
"InstallerPlugins", "JavaVM", "ExceptionHandling", "JavaFrameEmbedding",
// Deprecated so double Nope
"SyncServices", "CalendarStore",
};
static IEnumerable<string> _exclusionList;
static IEnumerable<string> ExclusionList {
get {
if (_exclusionList == null) {
switch (Helpers.Platform) {
case "osx":
_exclusionList = macOSXExclusionList;
break;
default:
_exclusionList = Enumerable.Empty <string> ();
break;
}
}
return _exclusionList;
}
}
public static bool DeclFilter (Decl d)
{
if (d.OwningModule != null) {
foreach (var item in ExclusionList)
if (d.InModule (item))
return false;
}
return true;
}
}
2016-05-26 16:06:52 +03:00
class AssemblyReader : IEnumerable<BaseVisitor> {
public void Load (string filename)
{
var ad = AssemblyDefinition.ReadAssembly (filename);
foreach (var v in Visitors) {
v.VisitManagedAssembly (ad);
foreach (var module in ad.Modules) {
v.VisitManagedModule (module);
if (!module.HasTypes)
continue;
foreach (var td in module.Types)
ProcessType (v, td);
}
}
}
void ProcessType (BaseVisitor v, TypeDefinition type)
{
v.VisitManagedType (type);
if (type.HasMethods) {
foreach (var md in type.Methods)
v.VisitManagedMethod (md);
}
if (type.HasNestedTypes) {
foreach (var nested in type.NestedTypes)
ProcessType (v, nested);
}
}
List<BaseVisitor> Visitors { get; } = new List<BaseVisitor> ();
public void Add (BaseVisitor visitor)
{
Visitors.Add (visitor);
}
public void End ()
{
foreach (var v in Visitors)
v.End ();
}
public IEnumerator<BaseVisitor> GetEnumerator ()
{
return Visitors.GetEnumerator ();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator ()
{
return Visitors.GetEnumerator ();
}
}
public class BaseVisitor : AstVisitor {
public virtual void VisitManagedAssembly (AssemblyDefinition assembly)
{
}
public virtual void VisitManagedModule (ModuleDefinition module)
{
}
public virtual void VisitManagedType (TypeDefinition type)
{
}
public virtual void VisitManagedMethod (MethodDefinition method)
{
}
// last chance to report errors
public virtual void End ()
{
}
2016-08-18 03:11:05 +03:00
protected string GetDeclaringHeaderFile (Decl decl)
{
var header_file = decl.PresumedLoc.FileName;
var fxh = header_file.IndexOf (".framework/Headers/", StringComparison.Ordinal);
if (fxh > 0) {
var start = header_file.LastIndexOf ('/', fxh) + 1;
return header_file.Substring (start, fxh - start);
}
return null;
}
2016-05-26 16:06:52 +03:00
}
// debug
class ListNative : BaseVisitor {
public override void VisitDecl (Decl decl)
{
if (decl is FunctionDecl)
;
else if (decl is VarDecl)
;
else if (decl is ObjCProtocolDecl)
;
else if (decl is ObjCInterfaceDecl)
;
else if (decl is EnumDecl)
;
else
Console.WriteLine ("{0}\t{1}", decl, decl.GetType ().Name);
}
}
2016-08-18 03:11:05 +03:00
}