Browse Source

Rename LibrarySymbolInfo to CSharpLibrarySymbolTable and improve it a bit

295227ce-f4a3-466b-a694-65c571873871
josetr 3 years ago
parent
commit
2792600efb
  1. 88
      src/Generator/Generators/CSharp/CSharpLibrarySymbolTable.cs
  2. 97
      src/Generator/Generators/CSharp/CSharpSources.cs
  3. 27
      src/Generator/Utils/TextGenerator.cs

88
src/Generator/Generators/CSharp/CSharpLibrarySymbolTable.cs

@ -0,0 +1,88 @@ @@ -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<string, string> symbols = new();
private readonly HashSet<string> 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;
}
}
}

97
src/Generator/Generators/CSharp/CSharpSources.cs

@ -22,7 +22,7 @@ namespace CppSharp.Generators.CSharp @@ -22,7 +22,7 @@ namespace CppSharp.Generators.CSharp
public CSharpTypePrinter TypePrinter { get; set; }
public CSharpExpressionPrinter ExpressionPrinter { get; protected set; }
Dictionary<string, LibrarySymbolInfo> LibrarySymbols = new Dictionary<string, LibrarySymbolInfo>();
internal Dictionary<string, CSharpLibrarySymbolTable> LibrarySymbolTables { get; } = new();
public override string FileExtension => "cs";
@ -100,7 +100,7 @@ namespace CppSharp.Generators.CSharp @@ -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 @@ -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 @@ -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<string, string> symbols = new Dictionary<string, string>();
private HashSet<string> uniqueVariableNames = new HashSet<string>();
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;
}
}
}
}

27
src/Generator/Utils/TextGenerator.cs

@ -76,6 +76,18 @@ namespace CppSharp @@ -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 @@ -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();
}
}
}

Loading…
Cancel
Save