Browse Source

Allow decompiling individual properties/methods.

pull/728/head
Daniel Grunwald 10 years ago
parent
commit
3cc83d9a41
  1. 14
      ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs
  2. 1
      ICSharpCode.Decompiler/IL/Transforms/ExpressionTransforms.cs
  3. 73
      ICSharpCode.Decompiler/TypeSystem/DecompilerTypeSystem.cs
  4. 44
      ILSpy/Languages/CSharpLanguage.cs

14
ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs

@ -287,6 +287,8 @@ namespace ICSharpCode.Decompiler.CSharp
var typeDefinition = def as TypeDefinition; var typeDefinition = def as TypeDefinition;
var methodDefinition = def as MethodDefinition; var methodDefinition = def as MethodDefinition;
var fieldDefinition = def as FieldDefinition; var fieldDefinition = def as FieldDefinition;
var propertyDefinition = def as PropertyDefinition;
var eventDefinition = def as EventDefinition;
if (typeDefinition != null) { if (typeDefinition != null) {
ITypeDefinition typeDef = typeSystem.Resolve(typeDefinition).GetDefinition(); ITypeDefinition typeDef = typeSystem.Resolve(typeDefinition).GetDefinition();
if (typeDef == null) if (typeDef == null)
@ -302,8 +304,18 @@ namespace ICSharpCode.Decompiler.CSharp
if (field == null) if (field == null)
throw new InvalidOperationException("Could not find field definition in NR type system"); throw new InvalidOperationException("Could not find field definition in NR type system");
syntaxTree.Members.Add(DoDecompile(fieldDefinition, field, new SimpleTypeResolveContext(field))); syntaxTree.Members.Add(DoDecompile(fieldDefinition, field, new SimpleTypeResolveContext(field)));
} else if (propertyDefinition != null) {
IProperty property = typeSystem.Resolve(propertyDefinition);
if (property == null)
throw new InvalidOperationException("Could not find field definition in NR type system");
syntaxTree.Members.Add(DoDecompile(propertyDefinition, property, new SimpleTypeResolveContext(property)));
} else if (eventDefinition != null) {
IEvent ev = typeSystem.Resolve(eventDefinition);
if (ev == null)
throw new InvalidOperationException("Could not find field definition in NR type system");
syntaxTree.Members.Add(DoDecompile(eventDefinition, ev, new SimpleTypeResolveContext(ev)));
} else { } else {
throw new NotImplementedException(); throw new NotSupportedException(def.GetType().Name);
} }
} }
RunTransforms(syntaxTree, new SimpleTypeResolveContext(typeSystem.MainAssembly)); RunTransforms(syntaxTree, new SimpleTypeResolveContext(typeSystem.MainAssembly));

1
ICSharpCode.Decompiler/IL/Transforms/ExpressionTransforms.cs

@ -72,6 +72,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
if (inst.Arguments.Count != inst.Method.Parameters.Count + 1) if (inst.Arguments.Count != inst.Method.Parameters.Count + 1)
return; return;
var newObj = new NewObj(inst.Method); var newObj = new NewObj(inst.Method);
newObj.ILRange = inst.ILRange;
newObj.Arguments.AddRange(inst.Arguments.Skip(1)); newObj.Arguments.AddRange(inst.Arguments.Skip(1));
var expr = new StObj(inst.Arguments[0], newObj, inst.Method.DeclaringType); var expr = new StObj(inst.Arguments[0], newObj, inst.Method.DeclaringType);
inst.ReplaceWith(expr); inst.ReplaceWith(expr);

73
ICSharpCode.Decompiler/TypeSystem/DecompilerTypeSystem.cs

@ -37,7 +37,9 @@ namespace ICSharpCode.Decompiler
Dictionary<IUnresolvedEntity, MemberReference> entityDict = new Dictionary<IUnresolvedEntity, MemberReference>(); Dictionary<IUnresolvedEntity, MemberReference> entityDict = new Dictionary<IUnresolvedEntity, MemberReference>();
Dictionary<FieldReference, IField> fieldLookupCache = new Dictionary<FieldReference, IField>(); Dictionary<FieldReference, IField> fieldLookupCache = new Dictionary<FieldReference, IField>();
Dictionary<PropertyReference, IProperty> propertyLookupCache = new Dictionary<PropertyReference, IProperty>();
Dictionary<MethodReference, IMethod> methodLookupCache = new Dictionary<MethodReference, IMethod>(); Dictionary<MethodReference, IMethod> methodLookupCache = new Dictionary<MethodReference, IMethod>();
Dictionary<EventReference, IEvent> eventLookupCache = new Dictionary<EventReference, IEvent>();
public DecompilerTypeSystem(ModuleDefinition moduleDefinition) public DecompilerTypeSystem(ModuleDefinition moduleDefinition)
{ {
@ -299,5 +301,76 @@ namespace ICSharpCode.Decompiler
} }
} }
#endregion #endregion
#region Resolve Property
public IProperty Resolve(PropertyReference propertyReference)
{
if (propertyReference == null)
throw new ArgumentNullException("propertyReference");
lock (propertyLookupCache) {
IProperty property;
if (!propertyLookupCache.TryGetValue(propertyReference, out property)) {
property = FindNonGenericProperty(propertyReference);
if (propertyReference.DeclaringType.IsGenericInstance) {
var git = (GenericInstanceType)propertyReference.DeclaringType;
var typeArguments = git.GenericArguments.SelectArray(Resolve);
property = (IProperty)property.Specialize(new TypeParameterSubstitution(typeArguments, null));
}
propertyLookupCache.Add(propertyReference, property);
}
return property;
}
}
IProperty FindNonGenericProperty(PropertyReference propertyReference)
{
ITypeDefinition typeDef = Resolve(propertyReference.DeclaringType).GetDefinition();
if (typeDef == null)
return null;
var parameterTypes = propertyReference.Parameters.SelectArray(p => Resolve(p.ParameterType));
var returnType = Resolve(propertyReference.PropertyType);
foreach (IProperty property in typeDef.Properties) {
if (property.Name == propertyReference.Name
&& CompareTypes(property.ReturnType, returnType)
&& CompareSignatures(property.Parameters, parameterTypes))
return property;
}
return null;
}
#endregion
#region Resolve Event
public IEvent Resolve(EventReference eventReference)
{
if (eventReference == null)
throw new ArgumentNullException("propertyReference");
lock (eventLookupCache) {
IEvent ev;
if (!eventLookupCache.TryGetValue(eventReference, out ev)) {
ev = FindNonGenericEvent(eventReference);
if (eventReference.DeclaringType.IsGenericInstance) {
var git = (GenericInstanceType)eventReference.DeclaringType;
var typeArguments = git.GenericArguments.SelectArray(Resolve);
ev = (IEvent)ev.Specialize(new TypeParameterSubstitution(typeArguments, null));
}
eventLookupCache.Add(eventReference, ev);
}
return ev;
}
}
IEvent FindNonGenericEvent(EventReference eventReference)
{
ITypeDefinition typeDef = Resolve(eventReference.DeclaringType).GetDefinition();
if (typeDef == null)
return null;
var returnType = Resolve(eventReference.EventType);
foreach (IEvent ev in typeDef.Events) {
if (ev.Name == eventReference.Name && CompareTypes(ev.ReturnType, returnType))
return ev;
}
return null;
}
#endregion
} }
} }

44
ILSpy/Languages/CSharpLanguage.cs

@ -90,13 +90,24 @@ namespace ICSharpCode.ILSpy
get { return ".csproj"; } get { return ".csproj"; }
} }
public override void DecompileMethod(MethodDefinition method, ITextOutput output, DecompilationOptions options) CSharpDecompiler CreateDecompiler(ModuleDefinition module, DecompilationOptions options)
{ {
WriteCommentLine(output, TypeToString(method.DeclaringType, includeNamespace: true)); CSharpDecompiler decompiler = new CSharpDecompiler(module, options.DecompilerSettings);
CSharpDecompiler decompiler = new CSharpDecompiler(method.Module, options.DecompilerSettings);
while (decompiler.AstTransforms.Count > transformCount) while (decompiler.AstTransforms.Count > transformCount)
decompiler.AstTransforms.RemoveAt(decompiler.AstTransforms.Count - 1); decompiler.AstTransforms.RemoveAt(decompiler.AstTransforms.Count - 1);
output.WriteLine(decompiler.Decompile(method).ToString()); return decompiler;
}
void WriteCode(ITextOutput output, SyntaxTree syntaxTree)
{
output.WriteLine(syntaxTree.ToString());
}
public override void DecompileMethod(MethodDefinition method, ITextOutput output, DecompilationOptions options)
{
WriteCommentLine(output, TypeToString(method.DeclaringType, includeNamespace: true));
CSharpDecompiler decompiler = CreateDecompiler(method.Module, options);
WriteCode(output, decompiler.Decompile(method));
/* /*
AstBuilder codeDomBuilder = CreateAstBuilder(options, currentType: method.DeclaringType, isSingleMember: true); AstBuilder codeDomBuilder = CreateAstBuilder(options, currentType: method.DeclaringType, isSingleMember: true);
if (method.IsConstructor && !method.IsStatic && !method.DeclaringType.IsValueType) { if (method.IsConstructor && !method.IsStatic && !method.DeclaringType.IsValueType) {
@ -147,15 +158,13 @@ namespace ICSharpCode.ILSpy
} }
*/ */
/*
public override void DecompileProperty(PropertyDefinition property, ITextOutput output, DecompilationOptions options) public override void DecompileProperty(PropertyDefinition property, ITextOutput output, DecompilationOptions options)
{ {
WriteCommentLine(output, TypeToString(property.DeclaringType, includeNamespace: true)); WriteCommentLine(output, TypeToString(property.DeclaringType, includeNamespace: true));
AstBuilder codeDomBuilder = CreateAstBuilder(options, currentType: property.DeclaringType, isSingleMember: true); CSharpDecompiler decompiler = CreateDecompiler(property.Module, options);
codeDomBuilder.AddProperty(property); WriteCode(output, decompiler.Decompile(property));
RunTransformsAndGenerateCode(codeDomBuilder, output, options);
} }
/*
public override void DecompileField(FieldDefinition field, ITextOutput output, DecompilationOptions options) public override void DecompileField(FieldDefinition field, ITextOutput output, DecompilationOptions options)
{ {
WriteCommentLine(output, TypeToString(field.DeclaringType, includeNamespace: true)); WriteCommentLine(output, TypeToString(field.DeclaringType, includeNamespace: true));
@ -203,22 +212,19 @@ namespace ICSharpCode.ILSpy
codeDomBuilder.AddMethod(ctor); codeDomBuilder.AddMethod(ctor);
} }
} }
*/
public override void DecompileEvent(EventDefinition ev, ITextOutput output, DecompilationOptions options) public override void DecompileEvent(EventDefinition ev, ITextOutput output, DecompilationOptions options)
{ {
WriteCommentLine(output, TypeToString(ev.DeclaringType, includeNamespace: true)); WriteCommentLine(output, TypeToString(ev.DeclaringType, includeNamespace: true));
AstBuilder codeDomBuilder = CreateAstBuilder(options, currentType: ev.DeclaringType, isSingleMember: true); CSharpDecompiler decompiler = CreateDecompiler(ev.Module, options);
codeDomBuilder.AddEvent(ev); WriteCode(output, decompiler.Decompile(ev));
RunTransformsAndGenerateCode(codeDomBuilder, output, options);
} }
*/
public override void DecompileType(TypeDefinition type, ITextOutput output, DecompilationOptions options) public override void DecompileType(TypeDefinition type, ITextOutput output, DecompilationOptions options)
{ {
CSharpDecompiler decompiler = new CSharpDecompiler(type.Module, options.DecompilerSettings); WriteCommentLine(output, TypeToString(type, includeNamespace: true));
output.WriteLine(decompiler.Decompile(type).ToString()); CSharpDecompiler decompiler = CreateDecompiler(type.Module, options);
// AstBuilder codeDomBuilder = CreateAstBuilder(options, currentType: type); WriteCode(output, decompiler.Decompile(type));
// codeDomBuilder.AddType(type);
// RunTransformsAndGenerateCode(codeDomBuilder, output, options);
} }
/* /*

Loading…
Cancel
Save