forked from ful-stackz/SharpCode
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathNamespaceBuilder.cs
More file actions
228 lines (202 loc) · 7.91 KB
/
NamespaceBuilder.cs
File metadata and controls
228 lines (202 loc) · 7.91 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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
using System.Collections.Generic;
using System.Linq;
using Optional.Collections;
namespace SharpCode
{
/// <summary>
/// Provides functionality for building namespaces. <see cref="NamespaceBuilder"/> instances are <b>not</b>
/// immutable.
/// </summary>
public class NamespaceBuilder
{
private static readonly AccessModifier[] AllowedMemberAccessModifiers = new AccessModifier[]
{
AccessModifier.None,
AccessModifier.Internal,
AccessModifier.Public,
};
private readonly Namespace _namespace = new Namespace();
private readonly List<ClassBuilder> _classes = new List<ClassBuilder>();
private readonly List<StructBuilder> _structs = new List<StructBuilder>();
private readonly List<InterfaceBuilder> _interfaces = new List<InterfaceBuilder>();
private readonly List<EnumBuilder> _enums = new List<EnumBuilder>();
internal NamespaceBuilder()
{
}
internal NamespaceBuilder(string name)
{
_namespace.Name = name;
}
/// <summary>
/// Sets the name of the namespace being built.
/// </summary>
public NamespaceBuilder WithName(string name)
{
_namespace.Name = name;
return this;
}
/// <summary>
/// Adds a using directive to the namespace being built.
/// </summary>
/// <param name="usingDirective">
/// The using directive to be added, for example <c>"System"</c> or <c>"System.Collections.Generic"</c>
/// The semi-colon at the end is optional.
/// </param>
public NamespaceBuilder WithUsing(string usingDirective)
{
_namespace.Usings.Add(usingDirective.Replace(";", string.Empty));
return this;
}
/// <summary>
/// Adds a class definition to the namespace being built.
/// </summary>
public NamespaceBuilder WithClass(ClassBuilder builder)
{
_classes.Add(builder);
return this;
}
/// <summary>
/// Adds a bunch of class definitions to the namespace being built.
/// </summary>
public NamespaceBuilder WithClasses(params ClassBuilder[] builders)
{
_classes.AddRange(builders);
return this;
}
/// <summary>
/// Adds a bunch of class definitions to the namespace being built.
/// </summary>
public NamespaceBuilder WithClasses(IEnumerable<ClassBuilder> builders)
{
_classes.AddRange(builders);
return this;
}
/// <summary>
/// Adds an interface definition to the namespace being built.
/// </summary>
public NamespaceBuilder WithInterface(InterfaceBuilder builder)
{
_interfaces.Add(builder);
return this;
}
/// <summary>
/// Adds a bunch of interface definitions to the namespace being built.
/// </summary>
public NamespaceBuilder WithInterfaces(params InterfaceBuilder[] builders)
{
_interfaces.AddRange(builders);
return this;
}
/// <summary>
/// Adds a bunch of interface definitions to the namespace being built.
/// </summary>
public NamespaceBuilder WithInterfaces(IEnumerable<InterfaceBuilder> builders)
{
_interfaces.AddRange(builders);
return this;
}
/// <summary>
/// Adds an enum definition to the namespace being built.
/// </summary>
public NamespaceBuilder WithEnum(EnumBuilder builder)
{
_enums.Add(builder);
return this;
}
/// <summary>
/// Adds a bunch of enum definitions to the namespace being built.
/// </summary>
public NamespaceBuilder WithEnums(params EnumBuilder[] builders)
{
_enums.AddRange(builders);
return this;
}
/// <summary>
/// Adds a bunch of enum definitions to the namespace being built.
/// </summary>
public NamespaceBuilder WithEnums(IEnumerable<EnumBuilder> builders)
{
_enums.AddRange(builders);
return this;
}
/// <summary>
/// Adds a struct to the namespace.
/// </summary>
/// <param name="builder">
/// The configuration of the struct.
/// </param>
public NamespaceBuilder WithStruct(StructBuilder builder)
{
_structs.Add(builder);
return this;
}
/// <summary>
/// Adds a bunch of structs to the namespace.
/// </summary>
/// <param name="builders">
/// A collection of structs which will be added to the namespace.
/// </param>
public NamespaceBuilder WithStructs(params StructBuilder[] builders)
{
_structs.AddRange(builders);
return this;
}
/// <summary>
/// Adds a bunch of structs to the namespace.
/// </summary>
/// <param name="builders">
/// A collection of structs which will be added to the namespace.
/// </param>
public NamespaceBuilder WithStructs(IEnumerable<StructBuilder> builders)
{
_structs.AddRange(builders);
return this;
}
/// <summary>
/// Returns the source code of the built namespace.
/// </summary>
/// <param name="formatted">
/// Indicates whether to format the source code.
/// </param>
public string ToSourceCode(bool formatted = true) =>
Build().ToSourceCode(formatted);
/// <summary>
/// Returns the source code of the built namespace.
/// </summary>
public override string ToString() =>
ToSourceCode();
internal Namespace Build()
{
if (string.IsNullOrWhiteSpace(_namespace.Name))
{
throw new MissingBuilderSettingException(
"Providing the name of the namespace is required when building a namespace.");
}
_namespace.Classes.AddRange(_classes.Select(builder => builder.Build()));
_namespace.Classes
.FirstOrNone(item => !AllowedMemberAccessModifiers.Contains(item.AccessModifier))
.MatchSome(item => throw new SyntaxException(
"A class defined under a namespace cannot have the access modifier " +
$"'{item.AccessModifier.ToSourceCode()}'."));
_namespace.Structs.AddRange(_structs.Select(builder => builder.Build()));
_namespace.Structs
.FirstOrNone(item => !AllowedMemberAccessModifiers.Contains(item.AccessModifier))
.MatchSome(item => throw new SyntaxException(
"A struct defined under a namespace cannot have the access modifier " +
$"'{item.AccessModifier.ToSourceCode()}'."));
_namespace.Interfaces.AddRange(_interfaces.Select(builder => builder.Build()));
_namespace.Interfaces
.FirstOrNone(item => !AllowedMemberAccessModifiers.Contains(item.AccessModifier))
.MatchSome(item => throw new SyntaxException(
"An interface defined under a namespace cannot have the access modifier " +
$"'{item.AccessModifier.ToSourceCode()}'."));
_namespace.Enums.AddRange(_enums.Select(builder => builder.Build()));
_namespace.Enums
.FirstOrNone(item => !AllowedMemberAccessModifiers.Contains(item.AccessModifier))
.MatchSome(item => throw new SyntaxException(
"An enum defined under a namespace cannot have the access modifier " +
$"'{item.AccessModifier.ToSourceCode()}'."));
return _namespace;
}
}
}