mirror of https://github.com/mono/CppSharp.git
3 changed files with 119 additions and 93 deletions
@ -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; |
||||
} |
||||
} |
||||
} |
Loading…
Reference in new issue