Browse Source

Move GeneratePropertyGetterForVariableWithInitializer to a class and create a whitelist for supported types

pg
josetr 3 years ago
parent
commit
0c7fb3ffd0
  1. 58
      src/Generator/Generators/CSharp/CSharpSources.cs
  2. 99
      src/Generator/Generators/CSharp/CSharpStaticVariableWithInitializerGenerator.cs

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

@ -1201,49 +1201,6 @@ internal static bool {Helpers.TryGetNativeToManagedMappingIdentifier}(IntPtr nat @@ -1201,49 +1201,6 @@ internal static bool {Helpers.TryGetNativeToManagedMappingIdentifier}(IntPtr nat
UnindentAndWriteCloseBrace();
}
private void GeneratePropertyGetterForVariableWithInitializer(Variable variable, string signature)
{
var initializerString = variable.Initializer.String;
Write($"{signature} {{ get; }} = ");
Type type = variable.Type.Desugar();
if (type is ArrayType arrayType)
{
var systemType = Internal.ExpressionHelper.GetSystemType(Context, arrayType.Type.Desugar());
Write($"new {arrayType.Type}[{arrayType.Size}] ");
Write("{ ");
List<string> elements = Internal.ExpressionHelper.SplitInitListExpr(initializerString);
while (elements.Count < arrayType.Size)
elements.Add(systemType == typeof(string) ? "\"\"" : null);
for (int i = 0; i < elements.Count; ++i)
{
var e = elements[i];
if (e == null)
Write("default");
else
{
if (!Internal.ExpressionHelper.TryParseExactLiteralExpression(ref e, systemType))
Write($"({arrayType.Type})");
Write(e);
}
if (i + 1 != elements.Count)
Write(", ");
}
Write(" }");
}
else
{
Write(initializerString);
}
WriteLine(";");
}
private void GeneratePropertyGetter<T>(T decl, Class @class,
bool isAbstract = false, Property property = null)
where T : Declaration, ITypedDecl
@ -1644,17 +1601,16 @@ internal static bool {Helpers.TryGetNativeToManagedMappingIdentifier}(IntPtr nat @@ -1644,17 +1601,16 @@ internal static bool {Helpers.TryGetNativeToManagedMappingIdentifier}(IntPtr nat
PushBlock(BlockKind.Variable);
GenerateDeclarationCommon(variable);
TypePrinter.PushMarshalKind(MarshalKind.ReturnVariableArray);
var variableType = variable.Type.Visit(TypePrinter);
TypePrinter.PopMarshalKind();
var signature = $"public static {variableType} {variable.Name}";
if (variable.Initializer != null && !string.IsNullOrWhiteSpace(variable.Initializer.String))
GeneratePropertyGetterForVariableWithInitializer(variable, signature);
if (CSharpStaticVariableWithInitializerGenerator.CanGenerate(variable))
Write(new CSharpStaticVariableWithInitializerGenerator(Context, variable, TypePrinter).Generate());
else
{
WriteLine(signature);
TypePrinter.PushMarshalKind(MarshalKind.ReturnVariableArray);
var variableType = variable.Type.Visit(TypePrinter);
TypePrinter.PopMarshalKind();
WriteLine($"public static {variableType} {variable.Name}");
WriteOpenBraceAndIndent();
GeneratePropertyGetter(variable, @class);

99
src/Generator/Generators/CSharp/CSharpStaticVariableWithInitializerGenerator.cs

@ -0,0 +1,99 @@ @@ -0,0 +1,99 @@
using CppSharp.AST;
using System.Collections.Generic;
using CppSharp.AST.Extensions;
namespace CppSharp.Generators.CSharp
{
internal class CSharpStaticVariableWithInitializerGenerator : TextGenerator
{
private readonly BindingContext context;
private readonly Variable variable;
private readonly CSharpTypePrinter typePrinter;
public CSharpStaticVariableWithInitializerGenerator(BindingContext context, Variable variable, CSharpTypePrinter typePrinter)
{
this.context = context;
this.variable = variable;
this.typePrinter = typePrinter;
}
public static bool CanGenerate(Variable variable)
{
if (variable.Initializer == null || string.IsNullOrWhiteSpace(variable.Initializer.String))
return false;
var arrayType = variable.Type.Desugar() as ArrayType;
var type = (arrayType?.Type ?? variable.Type).Desugar();
var isTypeSupported =
type.IsPrimitiveType() ||
type.IsPointerToPrimitiveType(PrimitiveType.Char) ||
type.IsPointerToPrimitiveType(PrimitiveType.WideChar) ||
(type.TryGetClass(out Class c) && c.IsValueType);
return isTypeSupported;
}
public string Generate()
{
typePrinter.PushMarshalKind(MarshalKind.ReturnVariableArray);
var variableType = variable.Type.Visit(typePrinter);
typePrinter.PopMarshalKind();
Write($"public static {variableType} {variable.Name} {{ get; }} = ");
if (variable.Type.Desugar() as ArrayType != null)
GenerateArrayInitializerExpression();
else
GenerateSimpleInitializerExpression();
WriteLine(";");
return ToString();
}
private void GenerateSimpleInitializerExpression()
{
var systemType = Internal.ExpressionHelper.GetSystemType(context, variable.Type.Desugar());
var initializerString = variable.Initializer.String;
if (Internal.ExpressionHelper.TryParseExactLiteralExpression(ref initializerString, systemType))
{
Write(initializerString);
return;
}
Write($"unchecked(({variable.Type}){initializerString})");
}
private void GenerateArrayInitializerExpression()
{
var arrayType = variable.Type.Desugar() as ArrayType;
var systemType = Internal.ExpressionHelper.GetSystemType(context, arrayType.Type.Desugar());
Write($"new {arrayType.Type}[{arrayType.Size}] {{");
List<string> elements = Internal.ExpressionHelper.SplitInitListExpr(variable.Initializer.String);
while (elements.Count < arrayType.Size)
elements.Add(systemType == typeof(string) ? "\"\"" : null);
for (int i = 0; i < elements.Count; ++i)
{
var e = elements[i];
if (e == null)
Write("default");
else
{
if (!Internal.ExpressionHelper.TryParseExactLiteralExpression(ref e, systemType))
Write($"unchecked(({arrayType.Type}){e})");
else
Write(e);
}
if (i + 1 != elements.Count)
Write(", ");
}
Write(" }");
}
}
}
Loading…
Cancel
Save