forked from SharpGenTools/SharpGenTools
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathCodeGeneratorBase.cs
More file actions
101 lines (81 loc) · 4.16 KB
/
Copy pathCodeGeneratorBase.cs
File metadata and controls
101 lines (81 loc) · 4.16 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
using System;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using SharpGen.Generator.Marshallers;
using SharpGen.Logging;
using SharpGen.Model;
using SharpGen.Transform;
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
namespace SharpGen.Generator;
public abstract class CodeGeneratorBase
{
private static readonly NameSyntax FieldOffsetName = ParseName("System.Runtime.InteropServices.FieldOffset");
protected GlobalNamespaceProvider GlobalNamespace => globalNamespace ??= Ioc.GlobalNamespace;
protected Logger Logger => logger ??= Ioc.Logger;
protected IGeneratorRegistry Generators => generators ??= Ioc.Generators;
protected IDocumentationLinker DocumentationLinker => documentationLinker ??= Ioc.DocumentationLinker;
protected ExternalDocCommentsReader ExternalDocReader => externalDocReader ??= Ioc.ExternalDocReader;
protected Ioc Ioc { get; }
private GlobalNamespaceProvider globalNamespace;
private Logger logger;
private IGeneratorRegistry generators;
private IDocumentationLinker documentationLinker;
private ExternalDocCommentsReader externalDocReader;
protected static readonly LiteralExpressionSyntax DefaultLiteral = MarshallerBase.DefaultLiteral;
protected static readonly LiteralExpressionSyntax NullLiteral = MarshallerBase.NullLiteral;
protected CodeGeneratorBase(Ioc ioc)
{
Ioc = ioc ?? throw new ArgumentNullException(nameof(ioc));
}
protected IMarshaller GetMarshaller(CsMarshalBase csElement) => Generators.Marshalling.GetMarshaller(csElement);
protected IRelationMarshaller GetRelationMarshaller(MarshallableRelation relation) =>
Generators.Marshalling.GetRelationMarshaller(relation);
private static AttributeSyntax FieldOffsetAttribute(SyntaxToken value) => Attribute(
FieldOffsetName,
AttributeArgumentList(
SingletonSeparatedList(
AttributeArgument(LiteralExpression(SyntaxKind.NumericLiteralExpression, value))
)
)
);
private static T AddFieldOffsetAttribute<T>(T member, int value, bool replace) where T : MemberDeclarationSyntax
{
if (replace)
RemoveAttribute(ref member, FieldOffsetName);
return (T) member.AddAttributeLists(
AttributeList(SingletonSeparatedList(FieldOffsetAttribute(Literal(value))))
);
}
private static void RemoveAttribute<T>(ref T member, NameSyntax attributeName) where T : MemberDeclarationSyntax
{
int outerIndex;
while ((outerIndex = AttributeListSearch(member)) != -1)
{
var oldAttributeList = member.AttributeLists[outerIndex];
var attributeList = oldAttributeList.Attributes;
int innerIndex;
while ((innerIndex = AttributeSearch(attributeList)) != -1)
{
attributeList = attributeList.RemoveAt(innerIndex);
}
var newAttributeList = attributeList.Count == 0
? member.AttributeLists.RemoveAt(outerIndex)
: member.AttributeLists.Replace(
oldAttributeList,
oldAttributeList.WithAttributes(attributeList)
);
member = (T) member.WithAttributeLists(newAttributeList);
}
int AttributeListSearch(T memberDeclarationSyntax) =>
memberDeclarationSyntax.AttributeLists.IndexOf(x => AttributeSearch(x.Attributes) != -1);
int AttributeSearch(SeparatedSyntaxList<AttributeSyntax> attributeListSyntax) =>
attributeListSyntax.IndexOf(x => x.Name.IsEquivalentTo(attributeName));
}
protected static T AddFieldOffsetAttribute<T>(T member, uint value, bool replace = false)
where T : MemberDeclarationSyntax =>
AddFieldOffsetAttribute(member, checked((int) value), replace);
protected static T AddFieldOffsetAttribute<T>(T member, long value, bool replace = false)
where T : MemberDeclarationSyntax =>
AddFieldOffsetAttribute(member, checked((int) value), replace);
}