Browse Source

Fix #1006

Fix threading issues and add missing null checks everywhere.
pull/1012/head
Siegfried Pammer 8 years ago
parent
commit
98e8ca2646
  1. 2
      ILSpy/Languages/CSharpLanguage.cs
  2. 5
      ILSpy/Languages/Language.cs
  3. 41
      ILSpy/LoadedAssembly.cs
  4. 18
      ILSpy/TreeNodes/Analyzer/AnalyzedAttributeAppliedToTreeNode.cs
  5. 19
      ILSpy/TreeNodes/Analyzer/ScopedWhereUsedAnalyzer.cs
  6. 2
      ILSpy/TreeNodes/AssemblyListTreeNode.cs
  7. 4
      ILSpy/TreeNodes/AssemblyTreeNode.cs

2
ILSpy/Languages/CSharpLanguage.cs

@ -288,7 +288,7 @@ namespace ICSharpCode.ILSpy
void AddReferenceWarningMessage(AssemblyDefinition assembly, ITextOutput output) void AddReferenceWarningMessage(AssemblyDefinition assembly, ITextOutput output)
{ {
var loadedAssembly = MainWindow.Instance.CurrentAssemblyList.GetAssemblies().FirstOrDefault(la => la.GetAssemblyDefinitionAsync().Result == assembly); var loadedAssembly = MainWindow.Instance.CurrentAssemblyList.GetAssemblies().FirstOrDefault(la => la.GetAssemblyDefinitionOrNull() == assembly);
if (loadedAssembly == null || !loadedAssembly.LoadedAssemblyReferencesInfo.HasErrors) if (loadedAssembly == null || !loadedAssembly.LoadedAssemblyReferencesInfo.HasErrors)
return; return;
const string line1 = "Warning: Some assembly references could not be loaded. This might lead to incorrect decompilation of some parts,"; const string line1 = "Warning: Some assembly references could not be loaded. This might lead to incorrect decompilation of some parts,";

5
ILSpy/Languages/Language.cs

@ -87,8 +87,9 @@ namespace ICSharpCode.ILSpy
public virtual void DecompileAssembly(LoadedAssembly assembly, ITextOutput output, DecompilationOptions options) public virtual void DecompileAssembly(LoadedAssembly assembly, ITextOutput output, DecompilationOptions options)
{ {
WriteCommentLine(output, assembly.FileName); WriteCommentLine(output, assembly.FileName);
if (assembly.GetAssemblyDefinitionAsync().Result != null) { var asm = assembly.GetAssemblyDefinitionOrNull();
var name = assembly.GetAssemblyDefinitionAsync().Result.Name; if (asm != null) {
var name = asm.Name;
if (name.IsWindowsRuntime) { if (name.IsWindowsRuntime) {
WriteCommentLine(output, name.Name + " [WinRT]"); WriteCommentLine(output, name.Name + " [WinRT]");
} else { } else {

41
ILSpy/LoadedAssembly.cs

@ -58,7 +58,7 @@ namespace ICSharpCode.ILSpy
/// </summary> /// </summary>
public async Task<string> GetTargetFrameworkIdAsync() public async Task<string> GetTargetFrameworkIdAsync()
{ {
var assembly = await GetAssemblyDefinitionAsync(); var assembly = await GetAssemblyDefinitionAsync().ConfigureAwait(false);
return assembly?.DetectTargetFrameworkId() ?? string.Empty; return assembly?.DetectTargetFrameworkId() ?? string.Empty;
} }
@ -66,22 +66,43 @@ namespace ICSharpCode.ILSpy
/// <summary> /// <summary>
/// Gets the Cecil ModuleDefinition. /// Gets the Cecil ModuleDefinition.
/// Can return null when there was a load error.
/// </summary> /// </summary>
public Task<ModuleDefinition> GetModuleDefinitionAsync() public Task<ModuleDefinition> GetModuleDefinitionAsync()
{ {
return assemblyTask; return assemblyTask;
} }
/// <summary>
/// Gets the Cecil ModuleDefinition.
/// Returns null in case of load errors.
/// </summary>
public ModuleDefinition GetModuleDefinitionOrNull()
{
try {
return GetModuleDefinitionAsync().Result;
} catch (Exception ex) {
System.Diagnostics.Trace.TraceError(ex.ToString());
return null;
}
}
/// <summary> /// <summary>
/// Gets the Cecil AssemblyDefinition. /// Gets the Cecil AssemblyDefinition.
/// Returns null when there was a load error; or when opening a netmodule.
/// </summary> /// </summary>
public async Task<AssemblyDefinition> GetAssemblyDefinitionAsync() public async Task<AssemblyDefinition> GetAssemblyDefinitionAsync()
{
var module = await assemblyTask.ConfigureAwait(false);
return module != null ? module.Assembly : null;
}
/// <summary>
/// Gets the Cecil AssemblyDefinition.
/// Returns null when there was a load error; or when opening a netmodule.
/// </summary>
public AssemblyDefinition GetAssemblyDefinitionOrNull()
{ {
try { try {
var module = await assemblyTask; return GetAssemblyDefinitionAsync().Result;
return module != null ? module.Assembly : null;
} catch (Exception ex) { } catch (Exception ex) {
System.Diagnostics.Trace.TraceError(ex.ToString()); System.Diagnostics.Trace.TraceError(ex.ToString());
return null; return null;
@ -97,7 +118,7 @@ namespace ICSharpCode.ILSpy
public string Text { public string Text {
get { get {
if (IsLoaded && !HasLoadError) { if (IsLoaded && !HasLoadError) {
return String.Format("{0} ({1})", ShortName, GetAssemblyDefinitionAsync().Result.Name.Version); return String.Format("{0} ({1})", ShortName, GetAssemblyDefinitionOrNull().Name.Version);
} else { } else {
return ShortName; return ShortName;
} }
@ -196,14 +217,12 @@ namespace ICSharpCode.ILSpy
public AssemblyDefinition Resolve(AssemblyNameReference name) public AssemblyDefinition Resolve(AssemblyNameReference name)
{ {
var node = parent.LookupReferencedAssembly(name); return parent.LookupReferencedAssembly(name)?.GetAssemblyDefinitionOrNull();
return node != null ? node.GetAssemblyDefinitionAsync().Result : null;
} }
public AssemblyDefinition Resolve(AssemblyNameReference name, ReaderParameters parameters) public AssemblyDefinition Resolve(AssemblyNameReference name, ReaderParameters parameters)
{ {
var node = parent.LookupReferencedAssembly(name); return parent.LookupReferencedAssembly(name)?.GetAssemblyDefinitionOrNull();
return node != null ? node.GetAssemblyDefinitionAsync().Result : null;
} }
public void Dispose() public void Dispose()
@ -243,7 +262,7 @@ namespace ICSharpCode.ILSpy
LoadedAssembly asm; LoadedAssembly asm;
lock (loadingAssemblies) { lock (loadingAssemblies) {
foreach (LoadedAssembly loaded in assemblyList.GetAssemblies()) { foreach (LoadedAssembly loaded in assemblyList.GetAssemblies()) {
var asmDef = loaded.GetAssemblyDefinitionAsync().Result; var asmDef = loaded.GetAssemblyDefinitionOrNull();
if (asmDef != null && data.fullName.Equals(data.isWinRT ? asmDef.Name.Name : asmDef.FullName, StringComparison.OrdinalIgnoreCase)) { if (asmDef != null && data.fullName.Equals(data.isWinRT ? asmDef.Name.Name : asmDef.FullName, StringComparison.OrdinalIgnoreCase)) {
return loaded; return loaded;
} }

18
ILSpy/TreeNodes/Analyzer/AnalyzedAttributeAppliedToTreeNode.cs

@ -295,21 +295,24 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
string requiredAssemblyFullName = asm.FullName; string requiredAssemblyFullName = asm.FullName;
IEnumerable<LoadedAssembly> assemblies = MainWindow.Instance.CurrentAssemblyList.GetAssemblies().Where(assy => assy.GetAssemblyDefinitionAsync().Result != null); IEnumerable<LoadedAssembly> assemblies = MainWindow.Instance.CurrentAssemblyList.GetAssemblies().Where(assy => assy.GetAssemblyDefinitionOrNull() != null);
foreach (var assembly in assemblies) { foreach (var assembly in assemblies) {
ct.ThrowIfCancellationRequested(); ct.ThrowIfCancellationRequested();
bool found = false; bool found = false;
foreach (var reference in assembly.GetAssemblyDefinitionAsync().Result.MainModule.AssemblyReferences) { var module = assembly.GetModuleDefinitionOrNull();
if (module == null)
continue;
foreach (var reference in module.AssemblyReferences) {
if (requiredAssemblyFullName == reference.FullName) { if (requiredAssemblyFullName == reference.FullName) {
found = true; found = true;
break; break;
} }
} }
if (found) { if (found) {
var typeref = GetScopeTypeReferenceInAssembly(assembly.GetAssemblyDefinitionAsync().Result); var typeref = GetScopeTypeReferenceInAssembly(module.Assembly);
if (typeref != null) if (typeref != null)
yield return new Tuple<AssemblyDefinition, TypeReference>(assembly.GetAssemblyDefinitionAsync().Result, typeref); yield return new Tuple<AssemblyDefinition, TypeReference>(module.Assembly, typeref);
} }
} }
} }
@ -333,10 +336,13 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
foreach (var assembly in assemblies) { foreach (var assembly in assemblies) {
ct.ThrowIfCancellationRequested(); ct.ThrowIfCancellationRequested();
var module = assembly.GetModuleDefinitionOrNull();
if (module == null)
continue;
if (friendAssemblies.Contains(assembly.ShortName)) { if (friendAssemblies.Contains(assembly.ShortName)) {
var typeref = GetScopeTypeReferenceInAssembly(assembly.GetAssemblyDefinitionAsync().Result); var typeref = GetScopeTypeReferenceInAssembly(module.Assembly);
if (typeref != null) { if (typeref != null) {
yield return new Tuple<AssemblyDefinition, TypeReference>(assembly.GetAssemblyDefinitionAsync().Result, typeref); yield return new Tuple<AssemblyDefinition, TypeReference>(module.Assembly, typeref);
} }
} }
} }

19
ILSpy/TreeNodes/Analyzer/ScopedWhereUsedAnalyzer.cs

@ -254,19 +254,22 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
string requiredAssemblyFullName = asm.FullName; string requiredAssemblyFullName = asm.FullName;
IEnumerable<LoadedAssembly> assemblies = MainWindow.Instance.CurrentAssemblyList.GetAssemblies().Where(assy => assy.GetAssemblyDefinitionAsync().Result != null); IEnumerable<LoadedAssembly> assemblies = MainWindow.Instance.CurrentAssemblyList.GetAssemblies().Where(assy => assy.GetAssemblyDefinitionOrNull() != null);
foreach (var assembly in assemblies) { foreach (var assembly in assemblies) {
ct.ThrowIfCancellationRequested(); ct.ThrowIfCancellationRequested();
bool found = false; bool found = false;
foreach (var reference in assembly.GetAssemblyDefinitionAsync().Result.MainModule.AssemblyReferences) { var module = assembly.GetModuleDefinitionOrNull();
if (module == null)
continue;
foreach (var reference in module.AssemblyReferences) {
if (requiredAssemblyFullName == reference.FullName) { if (requiredAssemblyFullName == reference.FullName) {
found = true; found = true;
break; break;
} }
} }
if (found && AssemblyReferencesScopeType(assembly.GetAssemblyDefinitionAsync().Result)) if (found && AssemblyReferencesScopeType(module.Assembly))
yield return assembly.GetAssemblyDefinitionAsync().Result; yield return module.Assembly;
} }
} }
@ -289,8 +292,12 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
foreach (var assembly in assemblies) { foreach (var assembly in assemblies) {
ct.ThrowIfCancellationRequested(); ct.ThrowIfCancellationRequested();
if (friendAssemblies.Contains(assembly.ShortName) && AssemblyReferencesScopeType(assembly.GetAssemblyDefinitionAsync().Result)) { if (friendAssemblies.Contains(assembly.ShortName)) {
yield return assembly.GetAssemblyDefinitionAsync().Result; var module = assembly.GetModuleDefinitionOrNull();
if (module == null)
continue;
if (AssemblyReferencesScopeType(module.Assembly))
yield return module.Assembly;
} }
} }
} }

2
ILSpy/TreeNodes/AssemblyListTreeNode.cs

@ -197,7 +197,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
return null; return null;
App.Current.Dispatcher.VerifyAccess(); App.Current.Dispatcher.VerifyAccess();
foreach (AssemblyTreeNode node in this.Children) { foreach (AssemblyTreeNode node in this.Children) {
if (node.LoadedAssembly.IsLoaded && node.LoadedAssembly.GetAssemblyDefinitionAsync().Result == asm) if (node.LoadedAssembly.IsLoaded && node.LoadedAssembly.GetAssemblyDefinitionOrNull() == asm)
return node; return node;
} }
return null; return null;

4
ILSpy/TreeNodes/AssemblyTreeNode.cs

@ -97,8 +97,8 @@ namespace ICSharpCode.ILSpy.TreeNodes
if (tooltip == null && assembly.IsLoaded) { if (tooltip == null && assembly.IsLoaded) {
tooltip = new TextBlock(); tooltip = new TextBlock();
var module = assembly.GetModuleDefinitionAsync().Result; var module = assembly.GetModuleDefinitionOrNull();
if (assembly.GetAssemblyDefinitionAsync().Result != null) { if (module.Assembly != null) {
tooltip.Inlines.Add(new Bold(new Run("Name: "))); tooltip.Inlines.Add(new Bold(new Run("Name: ")));
tooltip.Inlines.Add(new Run(module.Assembly.FullName)); tooltip.Inlines.Add(new Run(module.Assembly.FullName));
tooltip.Inlines.Add(new LineBreak()); tooltip.Inlines.Add(new LineBreak());

Loading…
Cancel
Save