in SharpGen/Generator/InterfaceCodeGenerator.cs [24:209]
public override IEnumerable<MemberDeclarationSyntax> GenerateCode(CsInterface csElement)
{
AttributeListSyntax attributes = null;
if (csElement.Guid != null)
{
attributes = AttributeList(SingletonSeparatedList(Attribute(ParseName("System.Runtime.InteropServices.GuidAttribute"),
AttributeArgumentList(SingletonSeparatedList(
AttributeArgument(
LiteralExpression(SyntaxKind.StringLiteralExpression, Literal(csElement.Guid))))))));
}
var baseList = default(BaseListSyntax);
if (csElement.Base != null || csElement.IBase != null)
{
baseList = BaseList();
if (csElement.Base != null)
{
baseList = baseList.AddTypes(SimpleBaseType(ParseTypeName(csElement.Base.QualifiedName)));
}
if (csElement.IBase != null)
{
baseList = baseList.AddTypes(SimpleBaseType(ParseTypeName(csElement.IBase.QualifiedName)));
}
}
var members = new List<MemberDeclarationSyntax>();
var nativePtr = Identifier("nativePtr");
if (!csElement.IsCallback)
{
ExpressionStatementSyntax InnerInterfaceSelector(CsInterface inner) =>
ExpressionStatement(
AssignmentExpression(
SyntaxKind.SimpleAssignmentExpression,
IdentifierName(inner.PropertyAccessName),
ObjectCreationExpression(ParseTypeName(inner.QualifiedName))
.WithArgumentList(
ArgumentList(SingletonSeparatedList(Argument(IdentifierName(nativePtr))))
)));
members.Add(
ConstructorDeclaration(
default,
TokenList(Token(SyntaxKind.PublicKeyword)),
Identifier(csElement.Name),
ParameterList(
SingletonSeparatedList(Parameter(nativePtr).WithType(GeneratorHelpers.IntPtrType))
),
ConstructorInitializer(
SyntaxKind.BaseConstructorInitializer,
ArgumentList(SingletonSeparatedList(Argument(IdentifierName(nativePtr))))
),
Block(List(csElement.InnerInterfaces.Select(InnerInterfaceSelector)))
));
members.Add(ConversionOperatorDeclaration(
default,
TokenList(Token(SyntaxKind.PublicKeyword), Token(SyntaxKind.StaticKeyword)),
Token(SyntaxKind.ExplicitKeyword),
IdentifierName(csElement.Name),
ParameterList(
SingletonSeparatedList(
Parameter(nativePtr).WithType(GeneratorHelpers.IntPtrType)
)),
default,
ArrowExpressionClause(
ConditionalExpression(
BinaryExpression(
SyntaxKind.EqualsExpression,
IdentifierName(nativePtr),
GeneratorHelpers.IntPtrZero
),
LiteralExpression(SyntaxKind.NullLiteralExpression),
ObjectCreationExpression(IdentifierName(csElement.Name))
.WithArgumentList(
ArgumentList(SingletonSeparatedList(Argument(IdentifierName(nativePtr))))
))))
.WithSemicolonToken(Token(SyntaxKind.SemicolonToken)));
}
members.AddRange(csElement.Variables.SelectMany(var => Generators.Constant.GenerateCode(var)));
if (csElement.HasInnerInterfaces)
{
static SyntaxTrivia GenerateXmlDoc(string value) => Trivia(
DocumentationCommentTrivia(
SyntaxKind.SingleLineDocumentationCommentTrivia,
List(
new XmlNodeSyntax[]
{
XmlDocStartSyntax,
XmlElement(
XmlDocSummaryStartSyntax,
SingletonList<XmlNodeSyntax>(XmlText(XmlTextLiteral(value))),
XmlDocSummaryEndSyntax
),
XmlDocEndSyntax
}
)
)
);
members.Add(
MethodDeclaration(
PredefinedType(Token(SyntaxKind.VoidKeyword)),
Identifier("NativePointerUpdated")
)
.WithModifiers(TokenList(Token(SyntaxKind.ProtectedKeyword), Token(SyntaxKind.OverrideKeyword)))
.WithParameterList(
ParameterList(
SingletonSeparatedList(
Parameter(Identifier("oldPointer")).WithType(GeneratorHelpers.IntPtrType)
)))
.WithBody(
Block(
SingletonList<StatementSyntax>(
ExpressionStatement(
InvocationExpression(
MemberAccessExpression(
SyntaxKind.SimpleMemberAccessExpression,
BaseExpression(),
IdentifierName("NativePointerUpdated")
))
.WithArgumentList(
ArgumentList(
SingletonSeparatedList(Argument(IdentifierName("oldPointer")))
))))
.AddRange(
csElement.InnerInterfaces.SelectMany(GenerateUpdateInnerInterface)
)))
.WithLeadingTrivia(GenerateXmlDoc("Update nested inner interfaces pointer"))
);
PropertyDeclarationSyntax InnerInterfaceSelector(CsInterface iface) =>
PropertyDeclaration(IdentifierName(iface.QualifiedName), Identifier(iface.PropertyAccessName))
.WithModifiers(TokenList(Token(SyntaxKind.PublicKeyword)))
.WithAccessorList(AccessorList(List(new[]
{
AccessorDeclaration(SyntaxKind.GetAccessorDeclaration)
.WithSemicolonToken(Token(SyntaxKind.SemicolonToken)),
AccessorDeclaration(SyntaxKind.SetAccessorDeclaration)
.WithModifiers(TokenList(Token(SyntaxKind.PrivateKeyword)))
.WithSemicolonToken(Token(SyntaxKind.SemicolonToken))
})))
.WithLeadingTrivia(GenerateXmlDoc($"Inner interface giving access to {iface.Name} methods."));
members.AddRange(csElement.InnerInterfaces.Select(InnerInterfaceSelector));
}
if (!csElement.IsCallback)
{
members.AddRange(csElement.Properties.SelectMany(prop => Generators.Property.GenerateCode(prop)));
}
foreach (var method in csElement.Methods)
{
members.AddRange(Generators.Method.GenerateCode(method));
}
if (csElement.IsCallback && csElement.AutoGenerateShadow)
{
yield return Generators.Shadow.GenerateCode(csElement);
var shadowAttribute = Attribute(GlobalNamespace.GetTypeNameSyntax(WellKnownName.ShadowAttribute))
.AddArgumentListArguments(AttributeArgument(TypeOfExpression(ParseTypeName(csElement.ShadowName))));
attributes = attributes?.AddAttributes(shadowAttribute) ?? AttributeList(SingletonSeparatedList(shadowAttribute));
}
var attributeList = attributes != null ? SingletonList(attributes) : default;
var modifiers = csElement.VisibilityTokenList
.Add(Token(SyntaxKind.PartialKeyword));
MemberDeclarationSyntax declaration = csElement.IsCallback
? InterfaceDeclaration(
attributeList, modifiers, Identifier(csElement.Name),
default, baseList, default, List(members)
)
: ClassDeclaration(
attributeList, modifiers, Identifier(csElement.Name),
default, baseList, default, List(members)
);
yield return AddDocumentationTrivia(declaration, csElement);
}