Browse Source

Simplify handling of initialisation of variables

Signed-off-by: Dimitar Dobrev <dpldobrev@protonmail.com>
pull/1641/head
Dimitar Dobrev 4 years ago
parent
commit
ad6557792f
  1. 1
      src/Generator/Generators/CSharp/CSharpExpressionPrinter.cs
  2. 21
      src/Generator/Generators/CSharp/CSharpSources.cs
  3. 39
      src/Generator/Passes/ExpressionHelper.cs
  4. 24
      src/Generator/Passes/HandleVariableInitializerPass.cs
  5. 6
      tests/CSharp/CSharp.cpp
  6. 3
      tests/CSharp/CSharp.h

1
src/Generator/Generators/CSharp/CSharpExpressionPrinter.cs

@ -1,7 +1,6 @@ @@ -1,7 +1,6 @@
using System.Linq;
using CppSharp.AST;
using CppSharp.AST.Extensions;
using CppSharp.Types;
using Type = CppSharp.AST.Type;
namespace CppSharp.Generators.CSharp

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

@ -1192,11 +1192,11 @@ namespace CppSharp.Generators.CSharp @@ -1192,11 +1192,11 @@ namespace CppSharp.Generators.CSharp
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);
elements.Add(systemType == typeof(string) ? "\"\"" : null);
for (int i = 0; i < elements.Count; ++i)
{
@ -1204,7 +1204,8 @@ namespace CppSharp.Generators.CSharp @@ -1204,7 +1204,8 @@ namespace CppSharp.Generators.CSharp
if (e == null)
Write("default");
else {
else
{
if (!Internal.ExpressionHelper.TryParseExactLiteralExpression(ref e, systemType))
Write($"({arrayType.Type})");
Write(e);
@ -1218,19 +1219,7 @@ namespace CppSharp.Generators.CSharp @@ -1218,19 +1219,7 @@ namespace CppSharp.Generators.CSharp
}
else
{
if (Internal.ExpressionHelper.PrintExpression(Context, null, type,
variable.Initializer, false, ref initializerString) == null)
{
Write(initializerString);
}
else
{
var systemType = Internal.ExpressionHelper.GetSystemType(Context, type);
if (!Internal.ExpressionHelper.TryParseExactLiteralExpression(ref initializerString, systemType))
Write($"({type}) {initializerString}");
else
Write(initializerString);
}
Write(initializerString);
}
WriteLine(";");
}

39
src/Generator/Passes/ExpressionHelper.cs

@ -11,7 +11,7 @@ using TypeCode = System.TypeCode; @@ -11,7 +11,7 @@ using TypeCode = System.TypeCode;
namespace CppSharp.Internal
{
internal class ExpressionHelper
internal static class ExpressionHelper
{
private static readonly Regex regexFunctionParams = new Regex(@"\(?(.+)\)?", RegexOptions.Compiled);
private static readonly Regex regexDoubleColon = new Regex(@"\w+::", RegexOptions.Compiled);
@ -200,7 +200,8 @@ namespace CppSharp.Internal @@ -200,7 +200,8 @@ namespace CppSharp.Internal
{
return CheckFloatSyntax(desugared, expression, ref result) ||
CheckForEnumValue(context, desugared, expression, ref result) ||
CheckForDefaultChar(context, desugared, ref result);
CheckForChar(context, desugared, ref result) ||
CheckForString(context, desugared, ref result);
}
private static bool CheckForDefaultPointer(BindingContext context, Type desugared, ref string result)
@ -390,10 +391,9 @@ namespace CppSharp.Internal @@ -390,10 +391,9 @@ namespace CppSharp.Internal
((BuiltinTypeExpressionObsolete)defaultArgument).Value == 0;
}
private static bool CheckForDefaultChar(BindingContext context, Type desugared, ref string result)
private static bool CheckForChar(BindingContext context, Type desugared, ref string result)
{
int value;
if (int.TryParse(result, out value) &&
if (int.TryParse(result, out int value) &&
((context.Options.MarshalCharAsManagedChar &&
desugared.IsPrimitiveType(PrimitiveType.Char)) ||
desugared.IsPrimitiveType(PrimitiveType.WideChar)))
@ -401,7 +401,36 @@ namespace CppSharp.Internal @@ -401,7 +401,36 @@ namespace CppSharp.Internal
result = value == 0 ? "'\\0'" : ("(char) " + result);
return true;
}
if (context.Options.MarshalCharAsManagedChar &&
desugared.IsPrimitiveType(PrimitiveType.UChar))
{
result = "(byte) " + result;
return true;
}
return false;
}
private static bool CheckForString(BindingContext context, Type desugared, ref string result)
{
if (context.TypeMaps.FindTypeMap(desugared, out TypeMap typeMap))
{
var typePrinterContext = new TypePrinterContext()
{
Kind = TypePrinterContextKind.Managed,
MarshalKind = MarshalKind.DefaultExpression,
Type = desugared
};
var typeInSignature = typeMap.CSharpSignatureType(typePrinterContext)
.SkipPointerRefs().Desugar();
if (typeInSignature is CILType managed && managed.Type == typeof(string))
{
result = result[result.IndexOf("\"")..];
return true;
}
}
return false;
}
}

24
src/Generator/Passes/HandleVariableInitializerPass.cs

@ -1,33 +1,21 @@ @@ -1,33 +1,21 @@
using CppSharp.AST;
using CppSharp.AST.Extensions;
using CppSharp.Internal;
namespace CppSharp.Passes
{
public class HandleVariableInitializerPass : TranslationUnitPass
{
public HandleVariableInitializerPass()
=> VisitOptions.ResetFlags(VisitFlags.NamespaceVariables);
public override bool VisitVariableDecl(Variable variable)
{
if (!base.VisitVariableDecl(variable) || variable.Ignore || variable.Initializer == null)
return false;
bool supported =
variable.Type.IsPrimitiveType() ||
variable.Type.IsPointerToPrimitiveType(PrimitiveType.Char) ||
variable.Type.IsPointerToPrimitiveType(PrimitiveType.WideChar) ||
(variable.Type is ArrayType arrayType && (
arrayType.Type.IsPrimitiveType() ||
arrayType.Type.IsPointerToPrimitiveType(PrimitiveType.Char) ||
arrayType.Type.IsPointerToPrimitiveType(PrimitiveType.WideChar)));
if (!supported)
{
variable.Initializer = null;
if (AlreadyVisited(variable) || variable.Ignore || variable.Initializer == null)
return false;
}
string initializerString = variable.Initializer.String;
ExpressionHelper.PrintExpression(Context, null, variable.Type, variable.Initializer, allowDefaultLiteral: true, ref initializerString);
ExpressionHelper.PrintExpression(Context, null, variable.Type, variable.Initializer,
allowDefaultLiteral: true, ref initializerString);
if (string.IsNullOrWhiteSpace(initializerString))
variable.Initializer = null;

6
tests/CSharp/CSharp.cpp

@ -613,7 +613,11 @@ void MethodsWithDefaultValues::defaultValueType(QGenericArgument valueType) @@ -613,7 +613,11 @@ void MethodsWithDefaultValues::defaultValueType(QGenericArgument valueType)
{
}
void MethodsWithDefaultValues::defaultChar(char c, char uc, char Uc, char Lc)
void MethodsWithDefaultValues::defaultChar(char c, char uc, char Uc, char Lc, unsigned char b)
{
}
void MethodsWithDefaultValues::defaultString(const wchar_t* wideString)
{
}

3
tests/CSharp/CSharp.h

@ -423,7 +423,8 @@ public: @@ -423,7 +423,8 @@ public:
void defaultVoidStar(void* ptr = 0);
void defaultFunctionPointer(void(*functionPtr)(int p) = nullptr);
void defaultValueType(QGenericArgument valueType = QGenericArgument());
void defaultChar(char c = 'a', char uc = u'u', char Uc = U'U', char Lc = L'L');
void defaultChar(char c = 'a', char uc = u'u', char Uc = U'U', char Lc = L'L', unsigned char b = 'z');
void defaultString(const wchar_t* wideString = L"Str");
void defaultEmptyChar(char c = 0);
void defaultEmptyEnum(Empty e = Empty(-1));
void defaultRefTypeBeforeOthers(Foo foo = Foo(), int i = 5, Bar::Items item = Bar::Item2);

Loading…
Cancel
Save