From 2792600efb86fa78cfb5143f419d9bc761d9f06c Mon Sep 17 00:00:00 2001 From: josetr <37419832+josetr@users.noreply.github.com> Date: Sat, 12 Mar 2022 22:23:40 +0000 Subject: [PATCH] Rename LibrarySymbolInfo to CSharpLibrarySymbolTable and improve it a bit --- .../CSharp/CSharpLibrarySymbolTable.cs | 88 +++++++++++++++++ .../Generators/CSharp/CSharpSources.cs | 97 +------------------ src/Generator/Utils/TextGenerator.cs | 27 ++++++ 3 files changed, 119 insertions(+), 93 deletions(-) create mode 100644 src/Generator/Generators/CSharp/CSharpLibrarySymbolTable.cs diff --git a/src/Generator/Generators/CSharp/CSharpLibrarySymbolTable.cs b/src/Generator/Generators/CSharp/CSharpLibrarySymbolTable.cs new file mode 100644 index 00000000..21f4ccd1 --- /dev/null +++ b/src/Generator/Generators/CSharp/CSharpLibrarySymbolTable.cs @@ -0,0 +1,88 @@ +using System.Collections.Generic; +using System.Text.RegularExpressions; + +namespace CppSharp.Generators.CSharp +{ + internal class CSharpLibrarySymbolTable : TextGenerator + { + private static readonly Regex identifierCleanerRegex = new(@"[^\w]", RegexOptions.Compiled); + private readonly Dictionary symbols = new(); + private readonly HashSet uniqueVariableNames = new(); + private readonly string path = string.Empty; + private readonly string @namespace = string.Empty; + private readonly string @class; + private int counter = 0; + + public CSharpLibrarySymbolTable(string path, string @namespace) + { + this.path = path; + @class = identifierCleanerRegex.Replace(path, "_"); + this.@namespace = (!string.IsNullOrEmpty(@namespace) ? @namespace : @class) + ".__Symbols"; + } + + public string Generate() + { + using (WriteBlock($"namespace {@namespace}")) + { + using (WriteBlock($"internal class {@class}")) + { + GenerateStaticVariables(); + + using (WriteBlock($"static {@class}()")) + GenerateStaticConstructorBody(); + } + } + + return ToString(); + } + + public void GenerateStaticVariables() + { + foreach (var symbol in symbols) + { + var variableIdentifier = symbol.Value; + WriteLine($"public static IntPtr {variableIdentifier} {{ get; }}"); + } + } + + public void GenerateStaticConstructorBody() + { + WriteLine($"var path = \"{path}\";"); + WriteLine("var image = CppSharp.SymbolResolver.LoadImage(ref path);"); + WriteLine("if (image == IntPtr.Zero) throw new global::System.DllNotFoundException(path);"); + + foreach (var symbol in symbols) + { + var mangled = symbol.Key; + var variableIdentifier = symbol.Value; + WriteLine($"{variableIdentifier} = CppSharp.SymbolResolver.ResolveSymbol(image, \"{mangled}\");"); + } + } + + public string GetFullVariablePath(string mangled) + { + return $"global::{@namespace}.{@class}." + GenerateUniqueVariableIdentifier(mangled); + } + + public string GenerateUniqueVariableIdentifier(string mangled) + { + if (!symbols.TryGetValue(mangled, out string result)) + { + result = identifierCleanerRegex.Replace(mangled, "_"); + if (!result.StartsWith("_")) + result = "_" + result; + + if (!uniqueVariableNames.Add(result)) + { + result += "_v"; + while (!uniqueVariableNames.Add(result)) + result += counter++; + } + + symbols[mangled] = result; + } + + return result; + } + } +} diff --git a/src/Generator/Generators/CSharp/CSharpSources.cs b/src/Generator/Generators/CSharp/CSharpSources.cs index 40f8eeec..ba47e47b 100644 --- a/src/Generator/Generators/CSharp/CSharpSources.cs +++ b/src/Generator/Generators/CSharp/CSharpSources.cs @@ -22,7 +22,7 @@ namespace CppSharp.Generators.CSharp public CSharpTypePrinter TypePrinter { get; set; } public CSharpExpressionPrinter ExpressionPrinter { get; protected set; } - Dictionary LibrarySymbols = new Dictionary(); + internal Dictionary LibrarySymbolTables { get; } = new(); public override string FileExtension => "cs"; @@ -100,7 +100,7 @@ namespace CppSharp.Generators.CSharp PopBlock(NewLineKind.BeforeNextBlock); } - foreach (var lib in LibrarySymbols) + foreach (var lib in LibrarySymbolTables) WriteLine(lib.Value.Generate()); GenerateExternalClassTemplateSpecializations(); @@ -1005,8 +1005,8 @@ internal static bool {Helpers.TryGetNativeToManagedMappingIdentifier}(IntPtr nat var libraryPath = GetLibraryOf(var); - if (!LibrarySymbols.TryGetValue(libraryPath, out var lib)) - LibrarySymbols[libraryPath] = lib = new LibrarySymbolInfo(libraryPath, Module.OutputNamespace); + if (!LibrarySymbolTables.TryGetValue(libraryPath, out var lib)) + LibrarySymbolTables[libraryPath] = lib = new CSharpLibrarySymbolTable(libraryPath, Module.OutputNamespace); var location = lib.GetFullVariablePath(var.Mangled); @@ -3609,94 +3609,5 @@ internal static{(@new ? " new" : string.Empty)} {printedClass} __GetInstance({Ty return obj.Type.Desugar().GetHashCode(); } } - - class LibrarySymbolInfo : TextGenerator - { - private static readonly Regex identifierCleanerRegex = new Regex(@"[^\w]", RegexOptions.Compiled); - private Dictionary symbols = new Dictionary(); - private HashSet uniqueVariableNames = new HashSet(); - private string path = ""; - private int counter = 0; - private string @class; - private string @namespace = ""; - - public LibrarySymbolInfo(string path, string @namespace) - { - this.path = path; - @class = identifierCleanerRegex.Replace(path, "_"); - this.@namespace = (!string.IsNullOrEmpty(@namespace) ? @namespace : @class) + ".__Symbols"; - } - - public string Generate() - { - WriteLine($"namespace {@namespace}"); - { - WriteOpenBraceAndIndent(); - WriteLine($"internal class {@class}"); - { - WriteOpenBraceAndIndent(); - GenerateStaticVariables(); - WriteLine($"static {@class}()"); - { - WriteOpenBraceAndIndent(); - GenerateStaticConstructorBody(); - UnindentAndWriteCloseBrace(); - } - UnindentAndWriteCloseBrace(); - } - UnindentAndWriteCloseBrace(); - } - return ToString(); - } - - public void GenerateStaticVariables() - { - foreach (var symbol in symbols) - { - var variableIdentifier = symbol.Value; - WriteLine($"public static IntPtr {variableIdentifier} {{ get; }}"); - } - } - - public void GenerateStaticConstructorBody() - { - WriteLine($"var path = \"{path}\";"); - WriteLine("var image = CppSharp.SymbolResolver.LoadImage(ref path);"); - WriteLine("if (image == IntPtr.Zero) throw new global::System.DllNotFoundException(path);"); - - foreach (var symbol in symbols) - { - var mangled = symbol.Key; - var variableIdentifier = symbol.Value; - WriteLine($"{variableIdentifier} = CppSharp.SymbolResolver.ResolveSymbol(image, \"{mangled}\");"); - } - } - - public string GetFullVariablePath(string mangled) - { - return $"global::{@namespace}.{@class}." + GenerateUniqueVariableIdentifier(mangled); - } - - public string GenerateUniqueVariableIdentifier(string mangled) - { - if (!symbols.TryGetValue(mangled, out string result)) - { - result = identifierCleanerRegex.Replace(mangled, "_"); - if (!result.StartsWith("_")) - result = "_" + result; - - if (!uniqueVariableNames.Add(result)) - { - result += "_v"; - while (!uniqueVariableNames.Add(result)) - result += counter++; - } - - symbols[mangled] = result; - } - - return result; - } - } } } diff --git a/src/Generator/Utils/TextGenerator.cs b/src/Generator/Utils/TextGenerator.cs index ed68d7a0..a57ae0c6 100644 --- a/src/Generator/Utils/TextGenerator.cs +++ b/src/Generator/Utils/TextGenerator.cs @@ -76,6 +76,18 @@ namespace CppSharp Unindent(); } + internal TextBlock WriteBlock(string msg) + { + WriteLine(msg); + WriteOpenBraceAndIndent(); + return new TextBlock(this); + } + + internal TextBlock WriteBlock((BlockKind kind, string msg) info) + { + return WriteBlock(info.msg); + } + public void NewLine() { StringBuilder.AppendLine(string.Empty); @@ -132,4 +144,19 @@ namespace CppSharp return tg.ToString(); } } + + internal ref struct TextBlock + { + private readonly ITextGenerator generator; + + public TextBlock(ITextGenerator generator) + { + this.generator = generator; + } + + public void Dispose() + { + generator.UnindentAndWriteCloseBrace(); + } + } }