Skip to content

Commit

Permalink
Merge pull request #1067 from gircore/improve-long-handling-2
Browse files Browse the repository at this point in the history
Improve long handling 2
  • Loading branch information
badcel authored Jun 7, 2024
2 parents ca38667 + d6fec7c commit 9b11472
Show file tree
Hide file tree
Showing 34 changed files with 782 additions and 147 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ internal static class CallbackParameters
new Parameter.PointerArray(),
new Parameter.PointerGLibArray(),
new Parameter.PointerGLibPtrArray(),
new Parameter.Long(), //Must be before primitive value type
new Parameter.UnsignedLong(), //Must be before primitive value type
new Parameter.PrimitiveValueType(),
new Parameter.PrimitiveValueTypeAlias(),
new Parameter.PrimitiveValueTypeArray(),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
using System;

namespace Generator.Renderer.Internal.Parameter;

internal class Long : ParameterConverter
{
public bool Supports(GirModel.AnyType anyType)
{
return anyType.Is<GirModel.Long>();
}

public RenderableParameter Convert(GirModel.Parameter parameter)
{
// If the parameter is both nullable and optional this implies a parameter type like 'int **' and possibly
// ownership transfer (this combination does not currently occur for any functions).
if (parameter is { Nullable: true, Optional: true })
throw new System.NotImplementedException($"{parameter.AnyTypeOrVarArgs} - Long value type with nullable=true and optional=true not yet supported");

// Nullable-only parameters likely have incorrect annotations and should be marked optional instead.
if (parameter.Nullable)
Log.Information($"Long value type '{parameter.Name}' with nullable=true is likely an incorrect annotation");

// The caller-allocates flag is not meaningful for primitive types (https://gitlab.gnome.org/GNOME/gobject-introspection/-/issues/446)
if (parameter.CallerAllocates)
Log.Information($"Long value type '{parameter.Name}' with caller-allocates=true is an incorrect annotation");

return new RenderableParameter(
Attribute: string.Empty,
Direction: GetDirection(parameter),
NullableTypeName: "CLong",
Name: Model.Parameter.GetName(parameter)
);
}

private static string GetDirection(GirModel.Parameter parameter) => parameter switch
{
// - Optional inout and out types are just exposed as non-nullable ref / out parameters which the user can ignore if desired.
{ Direction: GirModel.Direction.In, IsPointer: true } => ParameterDirection.Ref(),
{ Direction: GirModel.Direction.InOut } => ParameterDirection.Ref(),
{ Direction: GirModel.Direction.Out } => ParameterDirection.Out(),
{ Direction: GirModel.Direction.In } => ParameterDirection.In(),
_ => throw new Exception($"Can't figure out direction for internal long value type parameter {parameter}.")
};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
using System;

namespace Generator.Renderer.Internal.Parameter;

internal class UnsignedLong : ParameterConverter
{
public bool Supports(GirModel.AnyType anyType)
{
return anyType.Is<GirModel.UnsignedLong>();
}

public RenderableParameter Convert(GirModel.Parameter parameter)
{
// If the parameter is both nullable and optional this implies a parameter type like 'int **' and possibly
// ownership transfer (this combination does not currently occur for any functions).
if (parameter is { Nullable: true, Optional: true })
throw new System.NotImplementedException($"{parameter.AnyTypeOrVarArgs} - Unsigned long value type with nullable=true and optional=true not yet supported");

// Nullable-only parameters likely have incorrect annotations and should be marked optional instead.
if (parameter.Nullable)
Log.Information($"Unsigned long value type '{parameter.Name}' with nullable=true is likely an incorrect annotation");

// The caller-allocates flag is not meaningful for primitive types (https://gitlab.gnome.org/GNOME/gobject-introspection/-/issues/446)
if (parameter.CallerAllocates)
Log.Information($"Unsigned long value type '{parameter.Name}' with caller-allocates=true is an incorrect annotation");

return new RenderableParameter(
Attribute: string.Empty,
Direction: GetDirection(parameter),
NullableTypeName: "CULong",
Name: Model.Parameter.GetName(parameter)
);
}

private static string GetDirection(GirModel.Parameter parameter) => parameter switch
{
// - Optional inout and out types are just exposed as non-nullable ref / out parameters which the user can ignore if desired.
{ Direction: GirModel.Direction.In, IsPointer: true } => ParameterDirection.Ref(),
{ Direction: GirModel.Direction.InOut } => ParameterDirection.Ref(),
{ Direction: GirModel.Direction.Out } => ParameterDirection.Out(),
{ Direction: GirModel.Direction.In } => ParameterDirection.In(),
_ => throw new Exception($"Can't figure out direction for internal unsigned long value type parameter {parameter}.")
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ internal static class Parameters
new Parameter.PointerArray(),
new Parameter.PointerGLibArray(),
new Parameter.PointerGLibPtrArray(),
new Parameter.Long(), //Must be before primitive value type
new Parameter.UnsignedLong(), //Must be before primitive value type
new Parameter.PrimitiveValueType(),
new Parameter.PrimitiveValueTypeAlias(),
new Parameter.PrimitiveValueTypeArray(),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using System;
using System.Collections.Generic;

namespace Generator.Renderer.Internal.ParameterToManagedExpressions;

internal class Long : ToManagedParameterConverter
{
public bool Supports(GirModel.AnyType type)
=> type.Is<GirModel.Long>();

public void Initialize(ParameterToManagedData parameterData, IEnumerable<ParameterToManagedData> parameters)
{
switch (parameterData.Parameter)
{
case { Direction: GirModel.Direction.In, IsPointer: false }:
Direct(parameterData);
break;
default:
throw new NotImplementedException($"This kind of internal long value type (pointed: {parameterData.Parameter.IsPointer}, direction: {parameterData.Parameter.Direction} can't be converted to managed currently.");
}
}

private static void Direct(ParameterToManagedData parameterData)
{
var variableName = Model.Parameter.GetName(parameterData.Parameter);

parameterData.SetSignatureName(() => variableName);
parameterData.SetCallName(() => $"{variableName}.Value");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using System;
using System.Collections.Generic;

namespace Generator.Renderer.Internal.ParameterToManagedExpressions;

internal class UnsignedLong : ToManagedParameterConverter
{
public bool Supports(GirModel.AnyType type)
=> type.Is<GirModel.UnsignedLong>();

public void Initialize(ParameterToManagedData parameterData, IEnumerable<ParameterToManagedData> parameters)
{
switch (parameterData.Parameter)
{
case { Direction: GirModel.Direction.In, IsPointer: false }:
Direct(parameterData);
break;
default:
throw new NotImplementedException($"This kind of internal unsigned long value type (pointed: {parameterData.Parameter.IsPointer}, direction: {parameterData.Parameter.Direction} can't be converted to managed currently.");
}
}

private static void Direct(ParameterToManagedData parameterData)
{
var variableName = Model.Parameter.GetName(parameterData.Parameter);

parameterData.SetSignatureName(() => variableName);
parameterData.SetCallName(() => $"{variableName}.Value");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ internal static class ParameterToManagedExpression
new ParameterToManagedExpressions.PlatformStringArray(),
new ParameterToManagedExpressions.Pointer(),
new ParameterToManagedExpressions.PointerAlias(),
new ParameterToManagedExpressions.Long(), //Must be before primitive value type
new ParameterToManagedExpressions.UnsignedLong(), //Must be before primitive value type
new ParameterToManagedExpressions.PrimitiveValueType(),
new ParameterToManagedExpressions.PrimitiveValueTypeAlias(),
new ParameterToManagedExpressions.PrimitiveValueTypeArray(),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
namespace Generator.Renderer.Internal.ReturnType;

internal class Long : ReturnTypeConverter
{
public bool Supports(GirModel.ReturnType returnType)
{
return returnType.AnyType.Is<GirModel.Long>();
}

public RenderableReturnType Convert(GirModel.ReturnType returnType)
{
var nullableTypeName = returnType.IsPointer
? Model.Type.Pointer
: "CLong";

return new RenderableReturnType(nullableTypeName);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
namespace Generator.Renderer.Internal.ReturnType;

internal class UnsignedLong : ReturnTypeConverter
{
public bool Supports(GirModel.ReturnType returnType)
{
return returnType.AnyType.Is<GirModel.UnsignedLong>();
}

public RenderableReturnType Convert(GirModel.ReturnType returnType)
{
var nullableTypeName = returnType.IsPointer
? Model.Type.Pointer
: "CULong";

return new RenderableReturnType(nullableTypeName);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ internal static class ReturnTypeRenderer
new ReturnType.PlatformStringArray(),
new ReturnType.Pointer(),
new ReturnType.PointerAlias(),
new ReturnType.Long(), //Must be before primitive value type
new ReturnType.UnsignedLong(), //Must be before primitive value type
new ReturnType.PrimitiveValueType(),
new ReturnType.PrimitiveValueTypeAlias(),
new ReturnType.PrimitiveValueTypeArray(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ internal static class ReturnTypeRendererCallback
new ReturnType.PlatformStringInCallback(),
new ReturnType.PlatformStringArrayInCallback(),
new ReturnType.Pointer(),
new ReturnType.Long(),
new ReturnType.UnsignedLong(),
new ReturnType.PrimitiveValueType(),
new ReturnType.PrimitiveValueTypeAlias(),
new ReturnType.PrimitiveValueTypeArray(),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace Generator.Renderer.Internal.ReturnTypeToNativeExpressions;

internal class Long : ReturnTypeConverter
{
public bool Supports(GirModel.AnyType type)
=> type.Is<GirModel.Long>();

public string GetString(GirModel.ReturnType returnType, string fromVariableName)
=> $"new CLong(checked((nint){fromVariableName}))";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace Generator.Renderer.Internal.ReturnTypeToNativeExpressions;

internal class UnsigendLong : ReturnTypeConverter
{
public bool Supports(GirModel.AnyType type)
=> type.Is<GirModel.UnsignedLong>();

public string GetString(GirModel.ReturnType returnType, string fromVariableName)
=> $"new CULong(checked((nuint){fromVariableName}))";
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ internal static class ReturnTypeToNativeExpression
new ReturnTypeToNativeExpressions.OpaqueTypedRecord(),
new ReturnTypeToNativeExpressions.OpaqueUntypedRecord(),
new ReturnTypeToNativeExpressions.Pointer(),
new ReturnTypeToNativeExpressions.Long(), //Must be before Primitive value type
new ReturnTypeToNativeExpressions.UnsigendLong(), //Must be before primitive value type
new ReturnTypeToNativeExpressions.PrimitiveValueType(),
new ReturnTypeToNativeExpressions.PrimitiveValueTypeAlias(),
new ReturnTypeToNativeExpressions.TypedRecord(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ private static string GetNullableTypeName(GirModel.Field field)

private static string SetExpression(GirModel.Record record, GirModel.Field field)
{
return $"Handle.Set{Model.Field.GetName(field)}(new CLong((nint)value))";
return $"Handle.Set{Model.Field.GetName(field)}(new CLong(checked((nint)value)))";
}

private static string GetExpression(GirModel.Record record, GirModel.Field field)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ private static string GetNullableTypeName(GirModel.Field field)

private static string SetExpression(GirModel.Record record, GirModel.Field field)
{
return $"Handle.Set{Model.Field.GetName(field)}(new CULong((nuint)value))";
return $"Handle.Set{Model.Field.GetName(field)}(new CULong(checked((nuint)value)))";
}

private static string GetExpression(GirModel.Record record, GirModel.Field field)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using System;
using System.Collections.Generic;

namespace Generator.Renderer.Public.ParameterToNativeExpressions;

internal class Long : ToNativeParameterConverter
{
public bool Supports(GirModel.AnyType type)
=> type.Is<GirModel.Long>();

public void Initialize(ParameterToNativeData parameter, IEnumerable<ParameterToNativeData> _)
{
//Array length parameters are handled as part of the corresponding array converters
if (parameter.IsArrayLengthParameter)
return;

switch (parameter.Parameter)
{
case { IsPointer: false, Direction: GirModel.Direction.In }:
Direct(parameter);
break;
default:
throw new NotImplementedException($"{parameter.Parameter.AnyTypeOrVarArgs}: This long value type can not yet be converted to native");
}
}

private static void Direct(ParameterToNativeData parameter)
{
var parameterName = Model.Parameter.GetName(parameter.Parameter);
parameter.SetSignatureName(() => parameterName);
parameter.SetCallName(() => $"new CLong(checked((nint) {parameterName}))");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using System;
using System.Collections.Generic;

namespace Generator.Renderer.Public.ParameterToNativeExpressions;

internal class UnsignedLong : ToNativeParameterConverter
{
public bool Supports(GirModel.AnyType type)
=> type.Is<GirModel.UnsignedLong>();

public void Initialize(ParameterToNativeData parameter, IEnumerable<ParameterToNativeData> _)
{
//Array length parameters are handled as part of the corresponding array converters
if (parameter.IsArrayLengthParameter)
return;

switch (parameter.Parameter)
{
case { IsPointer: false, Direction: GirModel.Direction.In }:
Direct(parameter);
break;
default:
throw new NotImplementedException($"{parameter.Parameter.AnyTypeOrVarArgs}: This unsigned long value type can not yet be converted to native");
}
}

private static void Direct(ParameterToNativeData parameter)
{
var parameterName = Model.Parameter.GetName(parameter.Parameter);
parameter.SetSignatureName(() => parameterName);
parameter.SetCallName(() => $"new CULong(checked((nuint) {parameterName}))");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ internal static class ParameterToNativeExpression
new ParameterToNativeExpressions.PlatformStringArray(),
new ParameterToNativeExpressions.Pointer(),
new ParameterToNativeExpressions.PointerAlias(),
new ParameterToNativeExpressions.Long(), //Must be before primitive value type
new ParameterToNativeExpressions.UnsignedLong(), //Must be before primitive value type
new ParameterToNativeExpressions.PrimitiveValueType(),
new ParameterToNativeExpressions.PrimitiveValueTypeAlias(),
new ParameterToNativeExpressions.PrimitiveValueTypeArray(),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using GirModel;

namespace Generator.Renderer.Public.ReturnTypeToManagedExpressions;

internal class Long : ReturnTypeConverter
{
public bool Supports(AnyType type)
=> type.Is<GirModel.Long>();

public string GetString(GirModel.ReturnType returnType, string fromVariableName)
=> returnType.IsPointer
? fromVariableName
: $"{fromVariableName}.Value";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using GirModel;

namespace Generator.Renderer.Public.ReturnTypeToManagedExpressions;

internal class UnsignedLong : ReturnTypeConverter
{
public bool Supports(AnyType type)
=> type.Is<GirModel.UnsignedLong>();

public string GetString(GirModel.ReturnType returnType, string fromVariableName)
=> returnType.IsPointer
? fromVariableName
: $"{fromVariableName}.Value";
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ internal static class ReturnTypeToManagedExpression
new ReturnTypeToManagedExpressions.PlatformStringArray(),
new ReturnTypeToManagedExpressions.Pointer(),
new ReturnTypeToManagedExpressions.PointerAlias(),
new ReturnTypeToManagedExpressions.Long(), //Must be before primitive value type
new ReturnTypeToManagedExpressions.UnsignedLong(), //Must be before primitive value type
new ReturnTypeToManagedExpressions.PrimitiveValueType(),
new ReturnTypeToManagedExpressions.PrimitiveValueTypeAlias(),
new ReturnTypeToManagedExpressions.PrimitiveValueTypeArray(),
Expand Down
Loading

0 comments on commit 9b11472

Please sign in to comment.