Browse Source

Fix cancellation.

pull/832/head
Daniel Grunwald 8 years ago
parent
commit
867d330f1c
  1. 2
      ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs
  2. 8
      ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs
  3. 8
      ICSharpCode.Decompiler/CSharp/StatementBuilder.cs
  4. 8
      ICSharpCode.Decompiler/CSharp/Transforms/ReplaceMethodCallsWithOperators.cs
  5. 22
      ICSharpCode.Decompiler/CSharp/WholeProjectDecompiler.cs
  6. 4
      ILSpy/Languages/CSharpLanguage.cs

2
ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs

@ -633,7 +633,7 @@ namespace ICSharpCode.Decompiler.CSharp
} }
AddDefinesForConditionalAttributes(function); AddDefinesForConditionalAttributes(function);
var statementBuilder = new StatementBuilder(specializingTypeSystem, decompilationContext, method, function); var statementBuilder = new StatementBuilder(specializingTypeSystem, decompilationContext, method, function, CancellationToken);
var body = statementBuilder.ConvertAsBlock(function.Body); var body = statementBuilder.ConvertAsBlock(function.Body);
entityDecl.AddChild(body, Roles.Body); entityDecl.AddChild(body, Roles.Body);

8
ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs

@ -32,6 +32,7 @@ using ICSharpCode.Decompiler.TypeSystem.Implementation;
using ICSharpCode.Decompiler.Util; using ICSharpCode.Decompiler.Util;
using ExpressionType = System.Linq.Expressions.ExpressionType; using ExpressionType = System.Linq.Expressions.ExpressionType;
using PrimitiveType = ICSharpCode.Decompiler.CSharp.Syntax.PrimitiveType; using PrimitiveType = ICSharpCode.Decompiler.CSharp.Syntax.PrimitiveType;
using System.Threading;
namespace ICSharpCode.Decompiler.CSharp namespace ICSharpCode.Decompiler.CSharp
{ {
@ -65,12 +66,14 @@ namespace ICSharpCode.Decompiler.CSharp
internal readonly ICompilation compilation; internal readonly ICompilation compilation;
internal readonly CSharpResolver resolver; internal readonly CSharpResolver resolver;
readonly TypeSystemAstBuilder astBuilder; readonly TypeSystemAstBuilder astBuilder;
readonly CancellationToken cancellationToken;
public ExpressionBuilder(IDecompilerTypeSystem typeSystem, ITypeResolveContext decompilationContext) public ExpressionBuilder(IDecompilerTypeSystem typeSystem, ITypeResolveContext decompilationContext, CancellationToken cancellationToken)
{ {
Debug.Assert(decompilationContext != null); Debug.Assert(decompilationContext != null);
this.typeSystem = typeSystem; this.typeSystem = typeSystem;
this.decompilationContext = decompilationContext; this.decompilationContext = decompilationContext;
this.cancellationToken = cancellationToken;
this.compilation = decompilationContext.Compilation; this.compilation = decompilationContext.Compilation;
this.resolver = new CSharpResolver(new CSharpTypeResolveContext(compilation.MainAssembly, null, decompilationContext.CurrentTypeDefinition, decompilationContext.CurrentMember)); this.resolver = new CSharpResolver(new CSharpTypeResolveContext(compilation.MainAssembly, null, decompilationContext.CurrentTypeDefinition, decompilationContext.CurrentMember));
this.astBuilder = new TypeSystemAstBuilder(resolver); this.astBuilder = new TypeSystemAstBuilder(resolver);
@ -111,6 +114,7 @@ namespace ICSharpCode.Decompiler.CSharp
public TranslatedExpression Translate(ILInstruction inst, IType typeHint = null) public TranslatedExpression Translate(ILInstruction inst, IType typeHint = null)
{ {
Debug.Assert(inst != null); Debug.Assert(inst != null);
cancellationToken.ThrowIfCancellationRequested();
TranslationContext context = new TranslationContext { TranslationContext context = new TranslationContext {
TypeHint = typeHint ?? SpecialType.UnknownType TypeHint = typeHint ?? SpecialType.UnknownType
}; };
@ -943,7 +947,7 @@ namespace ICSharpCode.Decompiler.CSharp
AnonymousMethodExpression ame = new AnonymousMethodExpression(); AnonymousMethodExpression ame = new AnonymousMethodExpression();
ame.Parameters.AddRange(MakeParameters(method, function)); ame.Parameters.AddRange(MakeParameters(method, function));
ame.HasParameterList = true; ame.HasParameterList = true;
StatementBuilder builder = new StatementBuilder(typeSystem.GetSpecializingTypeSystem(new SimpleTypeResolveContext(method)), this.decompilationContext, method, function); StatementBuilder builder = new StatementBuilder(typeSystem.GetSpecializingTypeSystem(new SimpleTypeResolveContext(method)), this.decompilationContext, method, function, cancellationToken);
var body = builder.ConvertAsBlock(function.Body); var body = builder.ConvertAsBlock(function.Body);
bool isLambda = false; bool isLambda = false;
bool isMultiLineLambda = false; bool isMultiLineLambda = false;

8
ICSharpCode.Decompiler/CSharp/StatementBuilder.cs

@ -26,6 +26,7 @@ using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.Decompiler.Util; using ICSharpCode.Decompiler.Util;
using ICSharpCode.Decompiler.IL.Patterns; using ICSharpCode.Decompiler.IL.Patterns;
using System; using System;
using System.Threading;
namespace ICSharpCode.Decompiler.CSharp namespace ICSharpCode.Decompiler.CSharp
{ {
@ -34,17 +35,20 @@ namespace ICSharpCode.Decompiler.CSharp
internal readonly ExpressionBuilder exprBuilder; internal readonly ExpressionBuilder exprBuilder;
readonly ILFunction currentFunction; readonly ILFunction currentFunction;
readonly IMethod currentMethod; readonly IMethod currentMethod;
readonly CancellationToken cancellationToken;
public StatementBuilder(IDecompilerTypeSystem typeSystem, ITypeResolveContext decompilationContext, IMethod currentMethod, ILFunction currentFunction) public StatementBuilder(IDecompilerTypeSystem typeSystem, ITypeResolveContext decompilationContext, IMethod currentMethod, ILFunction currentFunction, CancellationToken cancellationToken)
{ {
Debug.Assert(typeSystem != null && decompilationContext != null && currentMethod != null); Debug.Assert(typeSystem != null && decompilationContext != null && currentMethod != null);
this.exprBuilder = new ExpressionBuilder(typeSystem, decompilationContext); this.exprBuilder = new ExpressionBuilder(typeSystem, decompilationContext, cancellationToken);
this.currentFunction = currentFunction; this.currentFunction = currentFunction;
this.currentMethod = currentMethod; this.currentMethod = currentMethod;
this.cancellationToken = cancellationToken;
} }
public Statement Convert(ILInstruction inst) public Statement Convert(ILInstruction inst)
{ {
cancellationToken.ThrowIfCancellationRequested();
return inst.AcceptVisitor(this); return inst.AcceptVisitor(this);
} }

8
ICSharpCode.Decompiler/CSharp/Transforms/ReplaceMethodCallsWithOperators.cs

@ -340,8 +340,12 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
void IAstTransform.Run(AstNode node, TransformContext context) void IAstTransform.Run(AstNode node, TransformContext context)
{ {
this.context = context; try {
node.AcceptVisitor(this); this.context = context;
node.AcceptVisitor(this);
} finally {
this.context = null;
}
} }
} }
} }

22
ICSharpCode.Decompiler/CSharp/WholeProjectDecompiler.cs

@ -30,6 +30,7 @@ using ICSharpCode.Decompiler.CSharp.Transforms;
using ICSharpCode.Decompiler.TypeSystem; using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.Decompiler.Util; using ICSharpCode.Decompiler.Util;
using Mono.Cecil; using Mono.Cecil;
using System.Threading;
namespace ICSharpCode.Decompiler.CSharp namespace ICSharpCode.Decompiler.CSharp
{ {
@ -73,22 +74,22 @@ namespace ICSharpCode.Decompiler.CSharp
/// </remarks> /// </remarks>
protected string targetDirectory; protected string targetDirectory;
public void DecompileProject(ModuleDefinition moduleDefinition, string targetDirectory) public void DecompileProject(ModuleDefinition moduleDefinition, string targetDirectory, CancellationToken cancellationToken = default(CancellationToken))
{ {
string projectFileName = Path.Combine(targetDirectory, CleanUpFileName(moduleDefinition.Assembly.Name.Name) + ".csproj"); string projectFileName = Path.Combine(targetDirectory, CleanUpFileName(moduleDefinition.Assembly.Name.Name) + ".csproj");
using (var writer = new StreamWriter(projectFileName)) { using (var writer = new StreamWriter(projectFileName)) {
DecompileProject(moduleDefinition, targetDirectory, writer); DecompileProject(moduleDefinition, targetDirectory, writer, cancellationToken);
} }
} }
public void DecompileProject(ModuleDefinition moduleDefinition, string targetDirectory, TextWriter projectFileWriter) public void DecompileProject(ModuleDefinition moduleDefinition, string targetDirectory, TextWriter projectFileWriter, CancellationToken cancellationToken = default(CancellationToken))
{ {
if (string.IsNullOrEmpty(targetDirectory)) { if (string.IsNullOrEmpty(targetDirectory)) {
throw new InvalidOperationException("Must set TargetDirectory"); throw new InvalidOperationException("Must set TargetDirectory");
} }
this.targetDirectory = targetDirectory; this.targetDirectory = targetDirectory;
directories.Clear(); directories.Clear();
var files = WriteCodeFilesInProject(moduleDefinition).ToList(); var files = WriteCodeFilesInProject(moduleDefinition, cancellationToken).ToList();
files.AddRange(WriteResourceFilesInProject(moduleDefinition)); files.AddRange(WriteResourceFilesInProject(moduleDefinition));
WriteProjectFile(projectFileWriter, files, moduleDefinition); WriteProjectFile(projectFileWriter, files, moduleDefinition);
} }
@ -248,9 +249,10 @@ namespace ICSharpCode.Decompiler.CSharp
return decompiler; return decompiler;
} }
IEnumerable<Tuple<string, string>> WriteAssemblyInfo(DecompilerTypeSystem ts) IEnumerable<Tuple<string, string>> WriteAssemblyInfo(DecompilerTypeSystem ts, CancellationToken cancellationToken)
{ {
var decompiler = CreateDecompiler(ts); var decompiler = CreateDecompiler(ts);
decompiler.CancellationToken = cancellationToken;
decompiler.AstTransforms.Add(new RemoveCompilerGeneratedAssemblyAttributes()); decompiler.AstTransforms.Add(new RemoveCompilerGeneratedAssemblyAttributes());
SyntaxTree syntaxTree = decompiler.DecompileModuleAndAssemblyAttributes(); SyntaxTree syntaxTree = decompiler.DecompileModuleAndAssemblyAttributes();
@ -264,7 +266,7 @@ namespace ICSharpCode.Decompiler.CSharp
return new Tuple<string, string>[] { Tuple.Create("Compile", assemblyInfo) }; return new Tuple<string, string>[] { Tuple.Create("Compile", assemblyInfo) };
} }
IEnumerable<Tuple<string, string>> WriteCodeFilesInProject(ModuleDefinition module) IEnumerable<Tuple<string, string>> WriteCodeFilesInProject(ModuleDefinition module, CancellationToken cancellationToken)
{ {
var files = module.Types.Where(IncludeTypeWhenDecompilingProject).GroupBy( var files = module.Types.Where(IncludeTypeWhenDecompilingProject).GroupBy(
delegate(TypeDefinition type) { delegate(TypeDefinition type) {
@ -281,15 +283,19 @@ namespace ICSharpCode.Decompiler.CSharp
DecompilerTypeSystem ts = new DecompilerTypeSystem(module); DecompilerTypeSystem ts = new DecompilerTypeSystem(module);
Parallel.ForEach( Parallel.ForEach(
files, files,
new ParallelOptions { MaxDegreeOfParallelism = this.MaxDegreeOfParallelism }, new ParallelOptions {
MaxDegreeOfParallelism = this.MaxDegreeOfParallelism,
CancellationToken = cancellationToken
},
delegate(IGrouping<string, TypeDefinition> file) { delegate(IGrouping<string, TypeDefinition> file) {
using (StreamWriter w = new StreamWriter(Path.Combine(targetDirectory, file.Key))) { using (StreamWriter w = new StreamWriter(Path.Combine(targetDirectory, file.Key))) {
CSharpDecompiler decompiler = CreateDecompiler(ts); CSharpDecompiler decompiler = CreateDecompiler(ts);
decompiler.CancellationToken = cancellationToken;
var syntaxTree = decompiler.DecompileTypes(file.ToArray()); var syntaxTree = decompiler.DecompileTypes(file.ToArray());
syntaxTree.AcceptVisitor(new CSharpOutputVisitor(w, settings.CSharpFormattingOptions)); syntaxTree.AcceptVisitor(new CSharpOutputVisitor(w, settings.CSharpFormattingOptions));
} }
}); });
return files.Select(f => Tuple.Create("Compile", f.Key)).Concat(WriteAssemblyInfo(ts)); return files.Select(f => Tuple.Create("Compile", f.Key)).Concat(WriteAssemblyInfo(ts, cancellationToken));
} }
#endregion #endregion

4
ILSpy/Languages/CSharpLanguage.cs

@ -87,6 +87,7 @@ namespace ICSharpCode.ILSpy
CSharpDecompiler CreateDecompiler(ModuleDefinition module, DecompilationOptions options) CSharpDecompiler CreateDecompiler(ModuleDefinition module, DecompilationOptions options)
{ {
CSharpDecompiler decompiler = new CSharpDecompiler(module, options.DecompilerSettings); CSharpDecompiler decompiler = new CSharpDecompiler(module, options.DecompilerSettings);
decompiler.CancellationToken = options.CancellationToken;
while (decompiler.AstTransforms.Count > transformCount) while (decompiler.AstTransforms.Count > transformCount)
decompiler.AstTransforms.RemoveAt(decompiler.AstTransforms.Count - 1); decompiler.AstTransforms.RemoveAt(decompiler.AstTransforms.Count - 1);
return decompiler; return decompiler;
@ -283,7 +284,7 @@ namespace ICSharpCode.ILSpy
if (options.FullDecompilation && options.SaveAsProjectDirectory != null) { if (options.FullDecompilation && options.SaveAsProjectDirectory != null) {
var decompiler = new ILSpyWholeProjectDecompiler(assembly, options); var decompiler = new ILSpyWholeProjectDecompiler(assembly, options);
decompiler.ProjectGuid = App.CommandLineArguments.FixedGuid; decompiler.ProjectGuid = App.CommandLineArguments.FixedGuid;
decompiler.DecompileProject(assembly.ModuleDefinition, options.SaveAsProjectDirectory, new TextOutputWriter(output)); decompiler.DecompileProject(assembly.ModuleDefinition, options.SaveAsProjectDirectory, new TextOutputWriter(output), options.CancellationToken);
} else { } else {
base.DecompileAssembly(assembly, output, options); base.DecompileAssembly(assembly, output, options);
output.WriteLine(); output.WriteLine();
@ -311,6 +312,7 @@ namespace ICSharpCode.ILSpy
// don't automatically load additional assemblies when an assembly node is selected in the tree view // don't automatically load additional assemblies when an assembly node is selected in the tree view
using (options.FullDecompilation ? null : LoadedAssembly.DisableAssemblyLoad()) { using (options.FullDecompilation ? null : LoadedAssembly.DisableAssemblyLoad()) {
CSharpDecompiler decompiler = new CSharpDecompiler(assembly.ModuleDefinition, options.DecompilerSettings); CSharpDecompiler decompiler = new CSharpDecompiler(assembly.ModuleDefinition, options.DecompilerSettings);
decompiler.CancellationToken = options.CancellationToken;
if (options.FullDecompilation) { if (options.FullDecompilation) {
SyntaxTree st = decompiler.DecompileWholeModuleAsSingleFile(); SyntaxTree st = decompiler.DecompileWholeModuleAsSingleFile();
output.WriteLine(st.ToString()); output.WriteLine(st.ToString());

Loading…
Cancel
Save