From e3b38a70f8d710af07732b325a6013ed18aa0fb0 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Wed, 25 Aug 2021 19:17:29 -0400 Subject: reorganize new classes --- .../Framework/ModLoading/Symbols/SymbolReader.cs | 51 ++++++++++++++++++++++ .../ModLoading/Symbols/SymbolReaderProvider.cs | 35 +++++++++++++++ .../ModLoading/Symbols/SymbolWriterProvider.cs | 22 ++++++++++ 3 files changed, 108 insertions(+) create mode 100644 src/SMAPI/Framework/ModLoading/Symbols/SymbolReader.cs create mode 100644 src/SMAPI/Framework/ModLoading/Symbols/SymbolReaderProvider.cs create mode 100644 src/SMAPI/Framework/ModLoading/Symbols/SymbolWriterProvider.cs (limited to 'src/SMAPI/Framework/ModLoading/Symbols') diff --git a/src/SMAPI/Framework/ModLoading/Symbols/SymbolReader.cs b/src/SMAPI/Framework/ModLoading/Symbols/SymbolReader.cs new file mode 100644 index 00000000..f1ae86a2 --- /dev/null +++ b/src/SMAPI/Framework/ModLoading/Symbols/SymbolReader.cs @@ -0,0 +1,51 @@ +using System; +using System.IO; +using Mono.Cecil; +using Mono.Cecil.Cil; +using Mono.Cecil.Pdb; + +namespace StardewModdingAPI.Framework.ModLoading.Symbols +{ + internal class SymbolReader : ISymbolReader + { + private ModuleDefinition Module; + private Stream Stream; + private ISymbolReader Using; + + public SymbolReader( ModuleDefinition module, Stream stream ) + { + this.Module = module; + this.Stream = stream; + this.Using = new NativePdbReaderProvider().GetSymbolReader( module, stream ); + } + + public void Dispose() + { + this.Using.Dispose(); + } + + public ISymbolWriterProvider GetWriterProvider() + { + return new PortablePdbWriterProvider(); + } + + public bool ProcessDebugHeader( ImageDebugHeader header ) + { + try + { + return this.Using.ProcessDebugHeader( header ); + } + catch (Exception e) + { + this.Using.Dispose(); + this.Using = new PortablePdbReaderProvider().GetSymbolReader( this.Module, this.Stream ); + return this.Using.ProcessDebugHeader( header ); + } + } + + public MethodDebugInformation Read( MethodDefinition method ) + { + return this.Using.Read( method ); + } + } +} diff --git a/src/SMAPI/Framework/ModLoading/Symbols/SymbolReaderProvider.cs b/src/SMAPI/Framework/ModLoading/Symbols/SymbolReaderProvider.cs new file mode 100644 index 00000000..e2a6d21e --- /dev/null +++ b/src/SMAPI/Framework/ModLoading/Symbols/SymbolReaderProvider.cs @@ -0,0 +1,35 @@ +using System.Collections.Generic; +using System.IO; +using Mono.Cecil; +using Mono.Cecil.Cil; + +namespace StardewModdingAPI.Framework.ModLoading.Symbols +{ + internal class SymbolReaderProvider : ISymbolReaderProvider + { + private readonly ISymbolReaderProvider BaseProvider = new DefaultSymbolReaderProvider(); + + private readonly Dictionary SymbolMapping = new Dictionary(); + + public void AddSymbolMapping( string dllName, Stream symbolStream ) + { + this.SymbolMapping.Add( dllName, symbolStream ); + } + + public ISymbolReader GetSymbolReader( ModuleDefinition module, string fileName ) + { + if ( this.SymbolMapping.ContainsKey( module.Name ) ) + return new SymbolReader( module, this.SymbolMapping[ module.Name ] ); + + return this.BaseProvider.GetSymbolReader( module, fileName ); + } + + public ISymbolReader GetSymbolReader( ModuleDefinition module, Stream symbolStream ) + { + if ( this.SymbolMapping.ContainsKey( module.Name ) ) + return new SymbolReader( module, this.SymbolMapping[ module.Name ] ); + + return this.BaseProvider.GetSymbolReader( module, symbolStream ); + } + } +} diff --git a/src/SMAPI/Framework/ModLoading/Symbols/SymbolWriterProvider.cs b/src/SMAPI/Framework/ModLoading/Symbols/SymbolWriterProvider.cs new file mode 100644 index 00000000..33e91db0 --- /dev/null +++ b/src/SMAPI/Framework/ModLoading/Symbols/SymbolWriterProvider.cs @@ -0,0 +1,22 @@ +using System.IO; +using Mono.Cecil; +using Mono.Cecil.Cil; + +namespace StardewModdingAPI.Framework.ModLoading.Symbols +{ + internal class SymbolWriterProvider : ISymbolWriterProvider + { + private readonly ISymbolWriterProvider BaseProvider = new DefaultSymbolWriterProvider(); + + public ISymbolWriter GetSymbolWriter( ModuleDefinition module, string fileName ) + { + return this.BaseProvider.GetSymbolWriter( module, fileName ); + } + + public ISymbolWriter GetSymbolWriter( ModuleDefinition module, Stream symbolStream ) + { + // Not implemented in default native pdb writer, so fallback to portable + return new PortablePdbWriterProvider().GetSymbolWriter( module, symbolStream ); + } + } +} -- cgit From 0b29eb3bc37553aa2e9776e17727ba07018606ea Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Wed, 25 Aug 2021 20:01:59 -0400 Subject: minor refactoring in new symbol code --- .../Framework/ModLoading/Symbols/SymbolReader.cs | 59 +++++++++++++++------- .../ModLoading/Symbols/SymbolReaderProvider.cs | 44 +++++++++++----- .../ModLoading/Symbols/SymbolWriterProvider.cs | 28 ++++++++-- 3 files changed, 94 insertions(+), 37 deletions(-) (limited to 'src/SMAPI/Framework/ModLoading/Symbols') diff --git a/src/SMAPI/Framework/ModLoading/Symbols/SymbolReader.cs b/src/SMAPI/Framework/ModLoading/Symbols/SymbolReader.cs index f1ae86a2..2171895d 100644 --- a/src/SMAPI/Framework/ModLoading/Symbols/SymbolReader.cs +++ b/src/SMAPI/Framework/ModLoading/Symbols/SymbolReader.cs @@ -1,4 +1,3 @@ -using System; using System.IO; using Mono.Cecil; using Mono.Cecil.Cil; @@ -6,46 +5,68 @@ using Mono.Cecil.Pdb; namespace StardewModdingAPI.Framework.ModLoading.Symbols { + /// Reads symbol data for an assembly. internal class SymbolReader : ISymbolReader { - private ModuleDefinition Module; - private Stream Stream; - private ISymbolReader Using; + /********* + ** Fields + *********/ + /// The module for which to read symbols. + private readonly ModuleDefinition Module; - public SymbolReader( ModuleDefinition module, Stream stream ) + /// The symbol file stream. + private readonly Stream Stream; + + /// The underlying symbol reader. + private ISymbolReader Reader; + + + /********* + ** Public methods + *********/ + /// Construct an instance. + /// The module for which to read symbols. + /// The symbol file stream. + public SymbolReader(ModuleDefinition module, Stream stream) { this.Module = module; this.Stream = stream; - this.Using = new NativePdbReaderProvider().GetSymbolReader( module, stream ); - } - - public void Dispose() - { - this.Using.Dispose(); + this.Reader = new NativePdbReaderProvider().GetSymbolReader(module, stream); } + /// Get the symbol writer provider for the assembly. public ISymbolWriterProvider GetWriterProvider() { return new PortablePdbWriterProvider(); } - public bool ProcessDebugHeader( ImageDebugHeader header ) + /// Process a debug header in the symbol file. + /// The debug header. + public bool ProcessDebugHeader(ImageDebugHeader header) { try { - return this.Using.ProcessDebugHeader( header ); + return this.Reader.ProcessDebugHeader(header); } - catch (Exception e) + catch { - this.Using.Dispose(); - this.Using = new PortablePdbReaderProvider().GetSymbolReader( this.Module, this.Stream ); - return this.Using.ProcessDebugHeader( header ); + this.Reader.Dispose(); + this.Reader = new PortablePdbReaderProvider().GetSymbolReader(this.Module, this.Stream); + return this.Reader.ProcessDebugHeader(header); } } - public MethodDebugInformation Read( MethodDefinition method ) + /// Read the method debug information for a method in the assembly. + /// The method definition. + public MethodDebugInformation Read(MethodDefinition method) + { + return this.Reader.Read(method); + } + + /// + public void Dispose() { - return this.Using.Read( method ); + this.Reader.Dispose(); } } } diff --git a/src/SMAPI/Framework/ModLoading/Symbols/SymbolReaderProvider.cs b/src/SMAPI/Framework/ModLoading/Symbols/SymbolReaderProvider.cs index e2a6d21e..02a70f1c 100644 --- a/src/SMAPI/Framework/ModLoading/Symbols/SymbolReaderProvider.cs +++ b/src/SMAPI/Framework/ModLoading/Symbols/SymbolReaderProvider.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; using System.IO; using Mono.Cecil; @@ -5,31 +6,48 @@ using Mono.Cecil.Cil; namespace StardewModdingAPI.Framework.ModLoading.Symbols { + /// Provides assembly symbol readers for Mono.Cecil. internal class SymbolReaderProvider : ISymbolReaderProvider { + /********* + ** Fields + *********/ + /// The underlying symbol reader provider. private readonly ISymbolReaderProvider BaseProvider = new DefaultSymbolReaderProvider(); - private readonly Dictionary SymbolMapping = new Dictionary(); + /// The symbol data loaded by absolute assembly path. + private readonly Dictionary SymbolsByAssemblyPath = new Dictionary(StringComparer.OrdinalIgnoreCase); - public void AddSymbolMapping( string dllName, Stream symbolStream ) + + /********* + ** Public methods + *********/ + /// Add the symbol file for a given assembly name, if it's not already registered. + /// The assembly file name. + /// The raw file stream for the symbols. + public void AddSymbolData(string fileName, Stream symbolStream) { - this.SymbolMapping.Add( dllName, symbolStream ); + this.SymbolsByAssemblyPath.Add(fileName, symbolStream); } - public ISymbolReader GetSymbolReader( ModuleDefinition module, string fileName ) + /// Get a symbol reader for a given module and assembly name. + /// The loaded assembly module. + /// The assembly file name. + public ISymbolReader GetSymbolReader(ModuleDefinition module, string fileName) { - if ( this.SymbolMapping.ContainsKey( module.Name ) ) - return new SymbolReader( module, this.SymbolMapping[ module.Name ] ); - - return this.BaseProvider.GetSymbolReader( module, fileName ); + return this.SymbolsByAssemblyPath.TryGetValue(module.Name, out Stream symbolData) + ? new SymbolReader(module, symbolData) + : this.BaseProvider.GetSymbolReader(module, fileName); } - public ISymbolReader GetSymbolReader( ModuleDefinition module, Stream symbolStream ) + /// Get a symbol reader for a given module and symbol stream. + /// The loaded assembly module. + /// The loaded symbol file stream. + public ISymbolReader GetSymbolReader(ModuleDefinition module, Stream symbolStream) { - if ( this.SymbolMapping.ContainsKey( module.Name ) ) - return new SymbolReader( module, this.SymbolMapping[ module.Name ] ); - - return this.BaseProvider.GetSymbolReader( module, symbolStream ); + return this.SymbolsByAssemblyPath.TryGetValue(module.Name, out Stream symbolData) + ? new SymbolReader(module, symbolData) + : this.BaseProvider.GetSymbolReader(module, symbolStream); } } } diff --git a/src/SMAPI/Framework/ModLoading/Symbols/SymbolWriterProvider.cs b/src/SMAPI/Framework/ModLoading/Symbols/SymbolWriterProvider.cs index 33e91db0..8f7e05d1 100644 --- a/src/SMAPI/Framework/ModLoading/Symbols/SymbolWriterProvider.cs +++ b/src/SMAPI/Framework/ModLoading/Symbols/SymbolWriterProvider.cs @@ -4,19 +4,37 @@ using Mono.Cecil.Cil; namespace StardewModdingAPI.Framework.ModLoading.Symbols { + /// Provides assembly symbol writers for Mono.Cecil. internal class SymbolWriterProvider : ISymbolWriterProvider { - private readonly ISymbolWriterProvider BaseProvider = new DefaultSymbolWriterProvider(); + /********* + ** Fields + *********/ + /// The default symbol writer provider. + private readonly ISymbolWriterProvider DefaultProvider = new DefaultSymbolWriterProvider(); - public ISymbolWriter GetSymbolWriter( ModuleDefinition module, string fileName ) + /// The symbol writer provider for the portable PDB format. + private readonly ISymbolWriterProvider PortablePdbProvider = new PortablePdbWriterProvider(); + + + /********* + ** Public methods + *********/ + /// Get a symbol writer for a given module and assembly path. + /// The loaded assembly module. + /// The assembly name. + public ISymbolWriter GetSymbolWriter(ModuleDefinition module, string fileName) { - return this.BaseProvider.GetSymbolWriter( module, fileName ); + return this.DefaultProvider.GetSymbolWriter(module, fileName); } - public ISymbolWriter GetSymbolWriter( ModuleDefinition module, Stream symbolStream ) + /// Get a symbol writer for a given module and symbol stream. + /// The loaded assembly module. + /// The loaded symbol file stream. + public ISymbolWriter GetSymbolWriter(ModuleDefinition module, Stream symbolStream) { // Not implemented in default native pdb writer, so fallback to portable - return new PortablePdbWriterProvider().GetSymbolWriter( module, symbolStream ); + return this.PortablePdbProvider.GetSymbolWriter(module, symbolStream); } } } -- cgit From 687a396e9c7581ebc2b35e58fc9b44d20d93a5d3 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Wed, 25 Aug 2021 20:02:51 -0400 Subject: fix error when reading a duplicate assembly --- src/SMAPI/Framework/ModLoading/Symbols/SymbolReaderProvider.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src/SMAPI/Framework/ModLoading/Symbols') diff --git a/src/SMAPI/Framework/ModLoading/Symbols/SymbolReaderProvider.cs b/src/SMAPI/Framework/ModLoading/Symbols/SymbolReaderProvider.cs index 02a70f1c..1b160690 100644 --- a/src/SMAPI/Framework/ModLoading/Symbols/SymbolReaderProvider.cs +++ b/src/SMAPI/Framework/ModLoading/Symbols/SymbolReaderProvider.cs @@ -24,10 +24,11 @@ namespace StardewModdingAPI.Framework.ModLoading.Symbols *********/ /// Add the symbol file for a given assembly name, if it's not already registered. /// The assembly file name. - /// The raw file stream for the symbols. - public void AddSymbolData(string fileName, Stream symbolStream) + /// Get the raw file stream for the symbols. + public void TryAddSymbolData(string fileName, Func getSymbolStream) { - this.SymbolsByAssemblyPath.Add(fileName, symbolStream); + if (!this.SymbolsByAssemblyPath.ContainsKey(fileName)) + this.SymbolsByAssemblyPath.Add(fileName, getSymbolStream()); } /// Get a symbol reader for a given module and assembly name. -- cgit From 11ecd578e960379db609cae5f9922df11ae79820 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Wed, 25 Aug 2021 20:03:06 -0400 Subject: fix error when no symbols are found --- src/SMAPI/Framework/ModLoading/Symbols/SymbolReaderProvider.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/SMAPI/Framework/ModLoading/Symbols') diff --git a/src/SMAPI/Framework/ModLoading/Symbols/SymbolReaderProvider.cs b/src/SMAPI/Framework/ModLoading/Symbols/SymbolReaderProvider.cs index 1b160690..44074337 100644 --- a/src/SMAPI/Framework/ModLoading/Symbols/SymbolReaderProvider.cs +++ b/src/SMAPI/Framework/ModLoading/Symbols/SymbolReaderProvider.cs @@ -13,7 +13,7 @@ namespace StardewModdingAPI.Framework.ModLoading.Symbols ** Fields *********/ /// The underlying symbol reader provider. - private readonly ISymbolReaderProvider BaseProvider = new DefaultSymbolReaderProvider(); + private readonly ISymbolReaderProvider BaseProvider = new DefaultSymbolReaderProvider(throwIfNoSymbol: false); /// The symbol data loaded by absolute assembly path. private readonly Dictionary SymbolsByAssemblyPath = new Dictionary(StringComparer.OrdinalIgnoreCase); -- cgit