Skip to content
This repository has been archived by the owner on Jan 27, 2019. It is now read-only.

Commit

Permalink
Improve Caliburn.Micro compatibility for Message.Attach
Browse files Browse the repository at this point in the history
Fix #132
  • Loading branch information
yck1509 committed Dec 9, 2014
1 parent efc4788 commit eebe95d
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 17 deletions.
22 changes: 12 additions & 10 deletions Confuser.Renamer/AnalyzePhase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,20 +66,22 @@ private void RegisterRenamers(ConfuserContext context, NameService service) {
foreach (var asmRef in module.GetAssemblyRefs()) {
if (asmRef.Name == "WindowsBase" || asmRef.Name == "PresentationCore" ||
asmRef.Name == "PresentationFramework" || asmRef.Name == "System.Xaml") {
if (!wpf) {
context.Logger.Debug("WPF found, enabling compatibility.");
service.Renamers.Add(new WPFAnalyzer());
wpf = true;
}
wpf = true;
}
else if (asmRef.Name == "Caliburn.Micro") {
if (!caliburn) {
context.Logger.Debug("Caliburn.Micro found, enabling compatibility.");
service.Renamers.Add(new CaliburnAnalyzer());
caliburn = true;
}
caliburn = true;
}
}

if (wpf) {
var wpfAnalyzer = new WPFAnalyzer();
context.Logger.Debug("WPF found, enabling compatibility.");
service.Renamers.Add(wpfAnalyzer);
if (caliburn) {
context.Logger.Debug("Caliburn.Micro found, enabling compatibility.");
service.Renamers.Add(new CaliburnAnalyzer(wpfAnalyzer));
}
}
}

internal void Analyze(NameService service, ConfuserContext context, ProtectionParameters parameters, IDnlibDef def, bool runAnalyzer) {
Expand Down
41 changes: 41 additions & 0 deletions Confuser.Renamer/Analyzers/CaliburnAnalyzer.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
using System;
using System.Text.RegularExpressions;
using Confuser.Core;
using Confuser.Renamer.BAML;
using dnlib.DotNet;

namespace Confuser.Renamer.Analyzers {
internal class CaliburnAnalyzer : IRenamer {

public CaliburnAnalyzer(WPFAnalyzer wpfAnalyzer) {
wpfAnalyzer.AnalyzeBAMLElement += AnalyzeBAMLElement;
}

public void Analyze(ConfuserContext context, INameService service, IDnlibDef def) {
var type = def as TypeDef;
if (type == null || type.DeclaringType != null)
Expand All @@ -19,6 +26,40 @@ public void Analyze(ConfuserContext context, INameService service, IDnlibDef def
}
}

private void AnalyzeBAMLElement(BAMLAnalyzer analyzer, BamlElement elem) {
foreach (var rec in elem.Body) {
var prop = rec as PropertyWithConverterRecord;
if (prop == null)
continue;
var attr = analyzer.ResolveAttribute(prop.AttributeId);
if (attr.Item2 == null || attr.Item2.Name != "Attach")
continue;
var attrDeclType = analyzer.ResolveType(attr.Item2.OwnerTypeId);
if (attrDeclType.FullName != "Caliburn.Micro.Message")
continue;

string actionStr = prop.Value;
foreach (var msg in actionStr.Split(';')) {
string msgStr;
if (msg.Contains("=")) {
msgStr = msg.Split('=')[1].Trim('[', ']', ' ');
}
else {
msgStr = msg.Trim('[', ']', ' ');
}
if (msgStr.StartsWith("Action"))
msgStr = msgStr.Substring(6);
int parenIndex = msgStr.IndexOf('(');
if (parenIndex != -1)
msgStr = msgStr.Substring(0, parenIndex);

string actName = msgStr.Trim();
foreach (var method in analyzer.LookupMethod(actName))
analyzer.NameService.SetCanRename(method, false);
}
}
}

public void PreRename(ConfuserContext context, INameService service, IDnlibDef def) {
//
}
Expand Down
6 changes: 5 additions & 1 deletion Confuser.Renamer/Analyzers/WPFAnalyzer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ internal class WPFAnalyzer : IRenamer {
private static readonly Regex ResourceNamePattern = new Regex("^.*\\.g\\.resources$");
private BAMLAnalyzer analyzer;

public event Action<BAMLAnalyzer, BamlElement> AnalyzeBAMLElement;

public void Analyze(ConfuserContext context, INameService service, IDnlibDef def) {
var method = def as MethodDef;
if (method != null) {
Expand Down Expand Up @@ -208,8 +210,10 @@ private void AnalyzeMethod(ConfuserContext context, INameService service, Method
}

private void AnalyzeResources(ConfuserContext context, INameService service, ModuleDefMD module) {
if (analyzer == null)
if (analyzer == null) {
analyzer = new BAMLAnalyzer(context, service);
analyzer.AnalyzeElement += AnalyzeBAMLElement;
}

var wpfResInfo = new Dictionary<string, Dictionary<string, BamlDocument>>();

Expand Down
53 changes: 47 additions & 6 deletions Confuser.Renamer/BAML/BAMLAnalyzer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,20 @@
namespace Confuser.Renamer.BAML {
internal class BAMLAnalyzer {

private readonly Dictionary<ushort, AssemblyDef> assemblyRefs = new Dictionary<ushort, AssemblyDef>();
private readonly Dictionary<ushort, Tuple<IDnlibDef, AttributeInfoRecord, TypeDef>> attrRefs = new Dictionary<ushort, Tuple<IDnlibDef, AttributeInfoRecord, TypeDef>>();
private readonly ConfuserContext context;
private readonly INameService service;

private readonly Dictionary<string, List<MethodDef>> methods = new Dictionary<string, List<MethodDef>>();
private readonly Dictionary<string, List<EventDef>> events = new Dictionary<string, List<EventDef>>();
private readonly Dictionary<string, List<PropertyDef>> properties = new Dictionary<string, List<PropertyDef>>();
private readonly INameService service;

private readonly Dictionary<ushort, AssemblyDef> assemblyRefs = new Dictionary<ushort, AssemblyDef>();
private readonly Dictionary<ushort, Tuple<IDnlibDef, AttributeInfoRecord, TypeDef>> attrRefs = new Dictionary<ushort, Tuple<IDnlibDef, AttributeInfoRecord, TypeDef>>();

private readonly Dictionary<ushort, StringInfoRecord> strings = new Dictionary<ushort, StringInfoRecord>();
private readonly Dictionary<ushort, TypeSig> typeRefs = new Dictionary<ushort, TypeSig>();
private readonly Dictionary<string, List<Tuple<AssemblyDef, string>>> xmlns = new Dictionary<string, List<Tuple<AssemblyDef, string>>>();

private string bamlName;
private ModuleDefMD module;
private IKnownThings things;
Expand All @@ -27,14 +32,21 @@ internal class BAMLAnalyzer {
private KnownThingsv4 thingsv4;
private XmlNsContext xmlnsCtx;

public event Action<BAMLAnalyzer, BamlElement> AnalyzeElement;

public ConfuserContext Context { get { return context; } }
public INameService NameService { get { return service; } }
public string CurrentBAMLName { get { return bamlName; } }
public ModuleDefMD Module { get { return module; } }

public BAMLAnalyzer(ConfuserContext context, INameService service) {
this.context = context;
this.service = service;
PreInit();
}

private void PreInit() {
// WPF will only look for public instance properties/events
// WPF will only look for public instance members
foreach (TypeDef type in context.Modules.SelectMany(m => m.GetTypes())) {
foreach (PropertyDef property in type.Properties) {
if (property.IsPublic() && !property.IsStatic())
Expand All @@ -45,9 +57,35 @@ private void PreInit() {
if (evt.IsPublic() && !evt.IsStatic())
events.AddListEntry(evt.Name, evt);
}

foreach (MethodDef method in type.Methods) {
if (method.IsPublic && !method.IsStatic)
methods.AddListEntry(method.Name, method);
}
}
}

public IEnumerable<PropertyDef> LookupProperty(string name) {
List<PropertyDef> ret;
if (!properties.TryGetValue(name, out ret))
return Enumerable.Empty<PropertyDef>();
return ret;
}

public IEnumerable<EventDef> LookupEvent(string name) {
List<EventDef> ret;
if (!events.TryGetValue(name, out ret))
return Enumerable.Empty<EventDef>();
return ret;
}

public IEnumerable<MethodDef> LookupMethod(string name) {
List<MethodDef> ret;
if (!methods.TryGetValue(name, out ret))
return Enumerable.Empty<MethodDef>();
return ret;
}

public BamlDocument Analyze(ModuleDefMD module, string bamlName, byte[] data) {
this.module = module;
this.bamlName = bamlName;
Expand Down Expand Up @@ -162,7 +200,7 @@ private void PopulateReferences(BamlDocument document) {
}
}

private TypeDef ResolveType(ushort typeId) {
public TypeDef ResolveType(ushort typeId) {
if ((short)typeId < 0)
return things.Types((KnownTypes)(-(short)typeId));
return typeRefs[typeId].ToBasicTypeDefOrRef().ResolveTypeDefThrow();
Expand Down Expand Up @@ -193,7 +231,7 @@ private TypeSig ResolveType(string typeName, out string prefix) {
return null;
}

private Tuple<IDnlibDef, AttributeInfoRecord, TypeDef> ResolveAttribute(ushort attrId) {
public Tuple<IDnlibDef, AttributeInfoRecord, TypeDef> ResolveAttribute(ushort attrId) {
if ((short)attrId < 0) {
Tuple<KnownTypes, PropertyDef, TypeDef> info = things.Properties((KnownProperties)(-(short)attrId));
return Tuple.Create<IDnlibDef, AttributeInfoRecord, TypeDef>(info.Item2, null, info.Item3);
Expand All @@ -214,6 +252,9 @@ private void AddTypeSigReference(TypeSig typeSig, INameReference<IDnlibDef> refe
private void ProcessBAMLElement(BamlElement root, BamlElement elem) {
ProcessElementHeader(elem);
ProcessElementBody(root, elem);

if (AnalyzeElement != null)
AnalyzeElement(this, elem);
}

private void ProcessElementHeader(BamlElement elem) {
Expand Down
4 changes: 4 additions & 0 deletions Confuser.Renamer/NameService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,10 @@ public void RegisterRenamer(IRenamer renamer) {
Renamers.Add(renamer);
}

public T FindRenamer<T>() {
return Renamers.OfType<T>().Single();
}

public void MarkHelper(IDnlibDef def, IMarkerService marker) {
if (marker.IsMarked(def))
return;
Expand Down

0 comments on commit eebe95d

Please sign in to comment.