Browse Source

#1180: Add IsWindowsFormsInitializeComponentMethod and disable some transforms when processing a Windows Forms InitializeComponent method.

pull/1213/head
Siegfried Pammer 7 years ago
parent
commit
023282a50d
  1. 21
      ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs
  2. 3
      ICSharpCode.Decompiler/CSharp/CallBuilder.cs
  3. 20
      ICSharpCode.Decompiler/CSharp/Transforms/IntroduceUsingDeclarations.cs
  4. 18
      ICSharpCode.Decompiler/DecompilerSettings.cs

21
ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs

@ -1146,6 +1146,11 @@ namespace ICSharpCode.Decompiler.CSharp @@ -1146,6 +1146,11 @@ namespace ICSharpCode.Decompiler.CSharp
return methodDecl;
}
internal static bool IsWindowsFormsInitializeComponentMethod(IMethod method)
{
return method.ReturnType.Kind == TypeKind.Void && method.Name == "InitializeComponent" && method.DeclaringTypeDefinition.GetNonInterfaceBaseTypes().Any(t => t.FullName == "System.Windows.Forms.Control");
}
void DecompileBody(MethodDefinition methodDefinition, IMethod method, EntityDeclaration entityDecl, DecompileRun decompileRun, ITypeResolveContext decompilationContext)
{
try {
@ -1165,7 +1170,15 @@ namespace ICSharpCode.Decompiler.CSharp @@ -1165,7 +1170,15 @@ namespace ICSharpCode.Decompiler.CSharp
}
}
var context = new ILTransformContext(function, specializingTypeSystem, settings) {
var localSettings = settings.Clone();
if (IsWindowsFormsInitializeComponentMethod(method)) {
localSettings.UseImplicitMethodGroupConversion = false;
localSettings.UsingDeclarations = false;
localSettings.FullyQualifyAmbiguousTypeNames = true;
localSettings.AlwaysCastTargetsOfExplicitInterfaceImplementationCalls = true;
}
var context = new ILTransformContext(function, specializingTypeSystem, localSettings) {
CancellationToken = CancellationToken,
DecompileRun = decompileRun
};
@ -1176,15 +1189,15 @@ namespace ICSharpCode.Decompiler.CSharp @@ -1176,15 +1189,15 @@ namespace ICSharpCode.Decompiler.CSharp
// When decompiling definitions only, we can cancel decompilation of all steps
// after yield and async detection, because only those are needed to properly set
// IsAsync/IsIterator flags on ILFunction.
if (!settings.DecompileMemberBodies && transform is AsyncAwaitDecompiler)
if (!localSettings.DecompileMemberBodies && transform is AsyncAwaitDecompiler)
break;
}
var body = BlockStatement.Null;
// Generate C# AST only if bodies should be displayed.
if (settings.DecompileMemberBodies) {
if (localSettings.DecompileMemberBodies) {
AddDefinesForConditionalAttributes(function, decompileRun, decompilationContext);
var statementBuilder = new StatementBuilder(specializingTypeSystem, decompilationContext, function, settings, CancellationToken);
var statementBuilder = new StatementBuilder(specializingTypeSystem, decompilationContext, function, localSettings, CancellationToken);
body = statementBuilder.ConvertAsBlock(function.Body);
Comment prev = null;

3
ICSharpCode.Decompiler/CSharp/CallBuilder.cs

@ -309,7 +309,8 @@ namespace ICSharpCode.Decompiler.CSharp @@ -309,7 +309,8 @@ namespace ICSharpCode.Decompiler.CSharp
typeArgumentList = ((MemberReferenceExpression)targetExpr).TypeArguments;
// HACK : convert this.Dispose() to ((IDisposable)this).Dispose(), if Dispose is an explicitly implemented interface method.
if (method.IsExplicitInterfaceImplementation && target.Expression is ThisReferenceExpression) {
// settings.AlwaysCastTargetsOfExplicitInterfaceImplementationCalls == true is used in Windows Forms' InitializeComponent methods.
if (method.IsExplicitInterfaceImplementation && (target.Expression is ThisReferenceExpression || settings.AlwaysCastTargetsOfExplicitInterfaceImplementationCalls)) {
var castExpression = new CastExpression(expressionBuilder.ConvertType(method.ImplementedInterfaceMembers[0].DeclaringType), target.Expression);
methodName = method.ImplementedInterfaceMembers[0].Name;
targetExpr = new MemberReferenceExpression(castExpression, methodName);

20
ICSharpCode.Decompiler/CSharp/Transforms/IntroduceUsingDeclarations.cs

@ -174,7 +174,25 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -174,7 +174,25 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
context.Pop();
}
}
public override void VisitMethodDeclaration(MethodDeclaration methodDeclaration)
{
if (methodDeclaration.GetSymbol() is IMethod method && CSharpDecompiler.IsWindowsFormsInitializeComponentMethod(method)) {
var previousContext = context.Peek();
var currentContext = new CSharpTypeResolveContext(previousContext.CurrentAssembly);
context.Push(currentContext);
try {
astBuilder = CreateAstBuilder(currentContext);
base.VisitMethodDeclaration(methodDeclaration);
} finally {
astBuilder = CreateAstBuilder(previousContext);
context.Pop();
}
} else {
base.VisitMethodDeclaration(methodDeclaration);
}
}
public override void VisitSimpleType(SimpleType simpleType)
{
TypeResolveResult rr;

18
ICSharpCode.Decompiler/DecompilerSettings.cs

@ -383,6 +383,24 @@ namespace ICSharpCode.Decompiler @@ -383,6 +383,24 @@ namespace ICSharpCode.Decompiler
}
}
bool alwaysCastTargetsOfExplicitInterfaceImplementationCalls = false;
/// <summary>
/// Gets/Sets whether to always cast targets to explicitly implemented methods.
/// true: <c>((ISupportInitialize)pictureBox1).BeginInit();</c>
/// false: <c>pictureBox1.BeginInit();</c>
/// default: false
/// </summary>
public bool AlwaysCastTargetsOfExplicitInterfaceImplementationCalls {
get { return alwaysCastTargetsOfExplicitInterfaceImplementationCalls; }
set {
if (alwaysCastTargetsOfExplicitInterfaceImplementationCalls != value) {
alwaysCastTargetsOfExplicitInterfaceImplementationCalls = value;
OnPropertyChanged();
}
}
}
bool fullyQualifyAmbiguousTypeNames = true;
public bool FullyQualifyAmbiguousTypeNames {

Loading…
Cancel
Save