Skip to content

Commit

Permalink
Split StdLib file per language
Browse files Browse the repository at this point in the history
  • Loading branch information
josetr committed Dec 10, 2020
1 parent 8ec03ed commit 6cefae8
Show file tree
Hide file tree
Showing 3 changed files with 707 additions and 712 deletions.
349 changes: 349 additions & 0 deletions src/Generator/Types/Std/Stdlib.CLI.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,349 @@
using System.Text;
using CppSharp.AST;
using CppSharp.AST.Extensions;
using CppSharp.Generators;
using CppSharp.Generators.AST;
using CppSharp.Generators.C;
using CppSharp.Generators.CLI;
using CppSharp.Generators.CSharp;

namespace CppSharp.Types.Std
{
[TypeMap("const char*", GeneratorKind = GeneratorKind.CLI)]
public partial class ConstCharPointer : TypeMap
{
public override Type CLISignatureType(TypePrinterContext ctx)
{
return new CILType(typeof(string));
}

public override void CLIMarshalToNative(MarshalContext ctx)
{
ctx.Before.WriteLine(
"auto _{0} = clix::marshalString<clix::E_UTF8>({1});",
ctx.ArgName, ctx.Parameter.Name);

ctx.Return.Write("_{0}.c_str()", ctx.ArgName);
}

public override void CLIMarshalToManaged(MarshalContext ctx)
{
if (ctx.Parameter != null && !ctx.Parameter.IsOut &&
!ctx.Parameter.IsInOut)
{
ctx.Return.Write(ctx.Parameter.Name);
return;
}

Type type = ctx.ReturnType.Type.Desugar();
Type pointee = type.GetPointee().Desugar();
var isChar = type.IsPointerToPrimitiveType(PrimitiveType.Char) ||
(pointee.IsPointerToPrimitiveType(PrimitiveType.Char) &&
ctx.Parameter != null &&
(ctx.Parameter.IsInOut || ctx.Parameter.IsOut));
var encoding = isChar ? Encoding.ASCII : Encoding.Unicode;

if (Equals(encoding, Encoding.ASCII))
encoding = Context.Options.Encoding;

string param;
if (Equals(encoding, Encoding.ASCII) || Equals(encoding, Encoding.UTF8))
param = "E_UTF8";
else if (Equals(encoding, Encoding.Unicode) ||
Equals(encoding, Encoding.BigEndianUnicode))
param = "E_UTF16";
else
throw new System.NotSupportedException(
$"{Context.Options.Encoding.EncodingName} is not supported yet.");

ctx.Return.Write(
$@"({ctx.ReturnVarName} == 0 ? nullptr : clix::marshalString<clix::{
param}>({ctx.ReturnVarName}))");
}
}

[TypeMap("const char[]", GeneratorKind = GeneratorKind.CLI)]
public partial class ConstCharArray : ConstCharPointer
{
}

[TypeMap("const wchar_t*", GeneratorKind = GeneratorKind.CLI)]
public partial class ConstWCharTPointer : ConstCharPointer
{
}

[TypeMap("const char16_t*", GeneratorKind = GeneratorKind.CLI)]
public partial class ConstChar16TPointer : ConstCharPointer
{
}

[TypeMap("const char32_t*", GeneratorKind = GeneratorKind.CLI)]
public partial class ConstChar32TPointer : ConstCharPointer
{
}

[TypeMap("basic_string<char, char_traits<char>, allocator<char>>", GeneratorKind = GeneratorKind.CLI)]
public partial class String : TypeMap
{
public override Type CLISignatureType(TypePrinterContext ctx)
{
return new CILType(typeof(string));
}

public override void CLIMarshalToNative(MarshalContext ctx)
{
ctx.Return.Write("clix::marshalString<clix::E_UTF8>({0})",
ctx.Parameter.Name);
}

public override void CLIMarshalToManaged(MarshalContext ctx)
{
ctx.Return.Write("clix::marshalString<clix::E_UTF8>({0})",
ctx.ReturnVarName);
}
}

[TypeMap("std::wstring", GeneratorKind = GeneratorKind.CLI)]
public partial class WString : TypeMap
{
public override Type CLISignatureType(TypePrinterContext ctx)
{
return new CILType(typeof(string));
}

public override void CLIMarshalToNative(MarshalContext ctx)
{
ctx.Return.Write("clix::marshalString<clix::E_UTF16>({0})",
ctx.Parameter.Name);
}

public override void CLIMarshalToManaged(MarshalContext ctx)
{
ctx.Return.Write("clix::marshalString<clix::E_UTF16>({0})",
ctx.ReturnVarName);
}
}

[TypeMap("std::vector", GeneratorKind = GeneratorKind.CLI)]
public partial class Vector : TypeMap
{
public override bool IsIgnored
{
get
{
var finalType = Type.GetFinalPointee() ?? Type;
var type = finalType as TemplateSpecializationType;
if (type == null)
{
var injectedClassNameType = (InjectedClassNameType) finalType;
type = (TemplateSpecializationType) injectedClassNameType.InjectedSpecializationType.Type;
}
var checker = new TypeIgnoreChecker(TypeMapDatabase);
type.Arguments[0].Type.Visit(checker);

return checker.IsIgnored;
}
}

public override Type CLISignatureType(TypePrinterContext ctx)
{
return new CustomType(
$"System::Collections::Generic::List<{ctx.GetTemplateParameterList()}>^");
}

public override void CLIMarshalToNative(MarshalContext ctx)
{
var desugared = Type.Desugar();
var templateType = desugared as TemplateSpecializationType;
var type = templateType.Arguments[0].Type;
var isPointerToPrimitive = type.Type.IsPointerToPrimitiveType();
var managedType = isPointerToPrimitive
? new CILType(typeof(System.IntPtr))
: type.Type;

var entryString = (ctx.Parameter != null) ? ctx.Parameter.Name
: ctx.ArgName;

var tmpVarName = "_tmp" + entryString;

var cppTypePrinter = new CppTypePrinter(Context);
var nativeType = type.Type.Visit(cppTypePrinter);

ctx.Before.WriteLine("auto {0} = std::vector<{1}>();",
tmpVarName, nativeType);
ctx.Before.WriteLine("for each({0} _element in {1})",
managedType, entryString);
ctx.Before.WriteOpenBraceAndIndent();
{
var param = new Parameter
{
Name = "_element",
QualifiedType = type
};

var elementCtx = new MarshalContext(ctx.Context, ctx.Indentation)
{
Parameter = param,
ArgName = param.Name,
};

var marshal = new CLIMarshalManagedToNativePrinter(elementCtx);
type.Type.Visit(marshal);

if (!string.IsNullOrWhiteSpace(marshal.Context.Before))
ctx.Before.Write(marshal.Context.Before);

if (isPointerToPrimitive)
ctx.Before.WriteLine("auto _marshalElement = {0}.ToPointer();",
marshal.Context.Return);
else
ctx.Before.WriteLine("auto _marshalElement = {0};",
marshal.Context.Return);

ctx.Before.WriteLine("{0}.push_back(_marshalElement);",
tmpVarName);
}

ctx.Before.UnindentAndWriteCloseBrace();

ctx.Return.Write(tmpVarName);
}

public override void CLIMarshalToManaged(MarshalContext ctx)
{
var desugared = Type.Desugar();
var templateType = desugared as TemplateSpecializationType;
var type = templateType.Arguments[0].Type;
var isPointerToPrimitive = type.Type.IsPointerToPrimitiveType();
var managedType = isPointerToPrimitive
? new CILType(typeof(System.IntPtr))
: type.Type;
var tmpVarName = "_tmp" + ctx.ArgName;

ctx.Before.WriteLine(
"auto {0} = gcnew System::Collections::Generic::List<{1}>();",
tmpVarName, managedType);

string retVarName = ctx.ReturnType.Type.Desugar().IsPointer() ? $"*{ctx.ReturnVarName}" : ctx.ReturnVarName;
ctx.Before.WriteLine("for(auto _element : {0})",
retVarName);
ctx.Before.WriteOpenBraceAndIndent();
{
var elementCtx = new MarshalContext(ctx.Context, ctx.Indentation)
{
ReturnVarName = "_element",
ReturnType = type
};

var marshal = new CLIMarshalNativeToManagedPrinter(elementCtx);
type.Type.Visit(marshal);

if (!string.IsNullOrWhiteSpace(marshal.Context.Before))
ctx.Before.Write(marshal.Context.Before);

ctx.Before.WriteLine("auto _marshalElement = {0};",
marshal.Context.Return);

if (isPointerToPrimitive)
ctx.Before.WriteLine("{0}->Add({1}(_marshalElement));",
tmpVarName, managedType);
else
ctx.Before.WriteLine("{0}->Add(_marshalElement);",
tmpVarName);
}
ctx.Before.UnindentAndWriteCloseBrace();

ctx.Return.Write(tmpVarName);
}
}

[TypeMap("std::map", GeneratorKind = GeneratorKind.CLI)]
public partial class Map : TypeMap
{
public override bool IsIgnored { get { return true; } }

public override Type CLISignatureType(TypePrinterContext ctx)
{
var type = Type as TemplateSpecializationType;
return new CustomType(
$@"System::Collections::Generic::Dictionary<{
type.Arguments[0].Type}, {type.Arguments[1].Type}>^");
}

public override void CLIMarshalToNative(MarshalContext ctx)
{
throw new System.NotImplementedException();
}

public override void CLIMarshalToManaged(MarshalContext ctx)
{
throw new System.NotImplementedException();
}

public override Type CSharpSignatureType(TypePrinterContext ctx)
{
if (ctx.Kind == TypePrinterContextKind.Native)
return new CustomType("Std.Map");

var type = Type as TemplateSpecializationType;
return new CustomType(
$@"System.Collections.Generic.Dictionary<{
type.Arguments[0].Type}, {type.Arguments[1].Type}>");
}
}

[TypeMap("std::list", GeneratorKind = GeneratorKind.CLI)]
public partial class List : TypeMap
{
public override bool IsIgnored { get { return true; } }
}

[TypeMap("std::shared_ptr", GeneratorKind = GeneratorKind.CLI)]
public partial class SharedPtr : TypeMap
{
public override bool IsIgnored { get { return true; } }
}

[TypeMap("basic_ostream<char, char_traits<char>>", GeneratorKind.CLI)]
public partial class OStream : TypeMap
{
public override Type CLISignatureType(TypePrinterContext ctx)
{
return new CILType(typeof(System.IO.TextWriter));
}

public override void CLIMarshalToNative(MarshalContext ctx)
{
var marshal = (CLIMarshalManagedToNativePrinter) ctx.MarshalToNative;
if (!ctx.Parameter.Type.Desugar().IsPointer())
marshal.ArgumentPrefix.Write("*");
var marshalCtxName = string.Format("ctx_{0}", ctx.Parameter.Name);
ctx.Before.WriteLine("msclr::interop::marshal_context {0};", marshalCtxName);
ctx.Return.Write("{0}.marshal_as<std::ostream*>({1})",
marshalCtxName, ctx.Parameter.Name);
}
}

[TypeMap("std::nullptr_t", GeneratorKind = GeneratorKind.CLI)]
public partial class NullPtr : TypeMap
{
public override bool DoesMarshalling { get { return false; } }

public override void CLITypeReference(CLITypeReferenceCollector collector,
ASTRecord<Declaration> loc)
{
var typeRef = collector.GetTypeReference(loc.Value);

if (typeRef != null)
{
var include = new CInclude
{
File = "cstddef",
Kind = CInclude.IncludeKind.Angled,
};

typeRef.Include = include;
}
}
}
}

0 comments on commit 6cefae8

Please sign in to comment.