in SharpGen/Generator/NativeStructCodeGenerator.cs [26:123]
public IEnumerable<MemberDeclarationSyntax> GenerateCode(CsStruct csStruct)
{
yield return StructDeclaration("__Native")
.WithModifiers(TokenList(Token(SyntaxKind.InternalKeyword), Token(SyntaxKind.PartialKeyword)))
.WithAttributeLists(SingletonList(GenerateStructLayoutAttribute(csStruct)))
.WithMembers(List(csStruct.Fields.SelectMany(GenerateMarshalStructField)));
if (csStruct.GenerateAsClass)
{
var methodName = IdentifierName("__MarshalFrom");
var marshalArgument = Argument(IdentifierName(MarshalParameterRefName))
.WithRefOrOutKeyword(Token(SyntaxKind.RefKeyword));
var invocationExpression = csStruct.IsStaticMarshal
? InvocationExpression(
methodName,
ArgumentList(
SeparatedList(
new[]
{
Argument(ThisExpression())
.WithRefOrOutKeyword(Token(SyntaxKind.RefKeyword)),
marshalArgument
}
)
)
)
: InvocationExpression(
methodName,
ArgumentList(SingletonSeparatedList(marshalArgument))
);
yield return ConstructorDeclaration(csStruct.Name)
.WithModifiers(TokenList(Token(SyntaxKind.PublicKeyword)))
.WithBody(Block());
yield return ConstructorDeclaration(csStruct.Name)
.WithModifiers(TokenList(Token(SyntaxKind.InternalKeyword)))
.WithParameterList(MarshalParameterListSyntax)
.WithBody(Block(ExpressionStatement(invocationExpression)));
}
yield return GenerateMarshalFree(csStruct);
yield return GenerateMarshalFrom(csStruct);
yield return GenerateMarshalTo(csStruct);
IEnumerable<MemberDeclarationSyntax> GenerateMarshalStructField(CsField field)
{
var fieldDecl = FieldDeclaration(VariableDeclaration(ParseTypeName(field.MarshalType.QualifiedName)))
.WithModifiers(TokenList(Token(SyntaxKind.PublicKeyword)));
if (csStruct.ExplicitLayout)
fieldDecl = AddFieldOffsetAttribute(fieldDecl, field.Offset);
if (field.ArraySpecification is {} arraySpecification)
{
yield return fieldDecl.WithDeclaration(
fieldDecl.Declaration.AddVariables(VariableDeclarator(field.Name))
);
if (arraySpecification.Dimension is { } dimension)
for (var i = 1; i < dimension; i++)
{
var declaration = fieldDecl.WithDeclaration(
fieldDecl.Declaration.AddVariables(VariableDeclarator($"__{field.Name}{i}"))
);
if (csStruct.ExplicitLayout)
{
var offset = field.Offset + i * field.Size / dimension;
declaration = AddFieldOffsetAttribute(declaration, offset, true);
}
yield return declaration;
}
else
Logger.Warning(
LoggingCodes.UnknownArrayDimension, "Unknown array dimensions for [{0}]",
field.QualifiedName
);
}
else if (field.HasNativeValueType)
{
yield return fieldDecl.WithDeclaration(
VariableDeclaration(
ParseTypeName($"{field.MarshalType.QualifiedName}.__Native"),
SingletonSeparatedList(VariableDeclarator(field.Name))
)
);
}
else
{
yield return fieldDecl.WithDeclaration(
fieldDecl.Declaration.AddVariables(VariableDeclarator(field.Name))
);
}
}
}