From 0c7fb3ffd092022ba0f9a9c3b59dda7899e031a0 Mon Sep 17 00:00:00 2001 From: josetr <37419832+josetr@users.noreply.github.com> Date: Sun, 13 Mar 2022 01:29:38 +0000 Subject: [PATCH] Move GeneratePropertyGetterForVariableWithInitializer to a class and create a whitelist for supported types --- .../Generators/CSharp/CSharpSources.cs | 58 ++--------- ...pStaticVariableWithInitializerGenerator.cs | 99 +++++++++++++++++++ 2 files changed, 106 insertions(+), 51 deletions(-) create mode 100644 src/Generator/Generators/CSharp/CSharpStaticVariableWithInitializerGenerator.cs diff --git a/src/Generator/Generators/CSharp/CSharpSources.cs b/src/Generator/Generators/CSharp/CSharpSources.cs index 03b97157..02cb11ec 100644 --- a/src/Generator/Generators/CSharp/CSharpSources.cs +++ b/src/Generator/Generators/CSharp/CSharpSources.cs @@ -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 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 decl, Class @class, bool isAbstract = false, Property property = null) where T : Declaration, ITypedDecl @@ -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); diff --git a/src/Generator/Generators/CSharp/CSharpStaticVariableWithInitializerGenerator.cs b/src/Generator/Generators/CSharp/CSharpStaticVariableWithInitializerGenerator.cs new file mode 100644 index 00000000..fd4d2455 --- /dev/null +++ b/src/Generator/Generators/CSharp/CSharpStaticVariableWithInitializerGenerator.cs @@ -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 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(" }"); + } + } +} \ No newline at end of file