Skip to content

Commit d72cb99

Browse files
committed
named constant
1 parent 936ca0d commit d72cb99

File tree

2 files changed

+86
-19
lines changed

2 files changed

+86
-19
lines changed

sandbox/GeneratorSandbox/Program.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,15 @@
88

99
var app = ConsoleApp.Create();
1010

11+
12+
1113
//
1214
// AddGlobalOption
1315

1416
app.ConfigureGlobalOptions((ref ConsoleApp.GlobalOptionsBuilder builder) =>
1517
{
18+
// builder.AddGlobalOption(description: "hoge", defaultValue: 0, "tako");
19+
1620
var verbose = builder.AddGlobalOption<bool>($"-v", "");
1721
var noColor = builder.AddGlobalOption<bool>("--no-color", "Don't colorize output.");
1822
var dryRun = builder.AddGlobalOption<bool>("--dry-run", "");

src/ConsoleAppFramework/Parser.cs

Lines changed: 82 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using Microsoft.CodeAnalysis.CSharp;
33
using Microsoft.CodeAnalysis.CSharp.Syntax;
44
using System.Collections.Immutable;
5+
using System.Runtime.InteropServices.ComTypes;
56

67
namespace ConsoleAppFramework;
78

@@ -215,39 +216,34 @@ public GlobalOptionInfo[] ParseGlobalOptions()
215216
{
216217
var node = x!.node;
217218
var memberAccess = x.expr!;
219+
var symbolInfo = model.GetSymbolInfo(memberAccess).Symbol as IMethodSymbol;
218220

219-
EquatableTypeSymbol typeSymbol = default!;
220-
string name = "";
221-
string description = "";
222221
bool isRequired = x.required;
223-
object? defaultValue = null;
222+
EquatableTypeSymbol typeSymbol = new(symbolInfo!.TypeArguments[0]);
224223

225-
var symbolInfo = model.GetSymbolInfo(memberAccess).Symbol as IMethodSymbol;
226-
typeSymbol = new(symbolInfo!.TypeArguments[0]);
224+
object? name = "";
225+
object? description = "";
226+
object? defaultValue = GetDefaultValue(typeSymbol.TypeSymbol);
227227

228-
var arguments = node.ArgumentList.Arguments;
229-
name = model.GetConstantValue(arguments[0].Expression).Value!.ToString();
228+
var arguments = node.ArgumentList;
230229

231-
if (arguments.Count >= 2)
230+
if (!isRequired)
232231
{
233-
description = model.GetConstantValue(arguments[1].Expression).Value!.ToString();
232+
// public T AddGlobalOption<T>([ConstantExpected] string name, [ConstantExpected] string description = "", [ConstantExpected] T defaultValue = default(T))
233+
GetArgumentConstantValues3(node.ArgumentList, model, "name", "description", "defaultValue", ref name, ref description, ref defaultValue);
234234
}
235-
236-
if (!isRequired)
235+
else
237236
{
238-
if (arguments.Count >= 3)
239-
{
240-
var constant = model.GetConstantValue(arguments[2].Expression);
241-
defaultValue = constant.Value!;
242-
}
237+
// public T AddRequiredGlobalOption<T>([ConstantExpected] string name, [ConstantExpected] string description = "")
238+
GetArgumentConstantValues2(node.ArgumentList, model, "name", "description", ref name, ref description);
243239
}
244240

245241
return new GlobalOptionInfo
246242
{
247243
Type = typeSymbol,
248244
IsRequired = isRequired,
249-
Name = name,
250-
Description = description,
245+
Name = (string)name!,
246+
Description = (string)description!,
251247
DefaultValue = defaultValue
252248
};
253249
})
@@ -256,6 +252,73 @@ public GlobalOptionInfo[] ParseGlobalOptions()
256252

257253
return result;
258254

255+
static void GetArgumentConstantValues2(ArgumentListSyntax argumentListSyntax, SemanticModel model, string name1, string name2, ref object? value1, ref object? value2)
256+
{
257+
var arguments = argumentListSyntax.Arguments;
258+
for (int i = 0; i < arguments.Count; i++)
259+
{
260+
var arg = arguments[i];
261+
var constant = model.GetConstantValue(arg.Expression);
262+
if (constant.HasValue)
263+
{
264+
var constantValue = constant.Value;
265+
if (arg.NameColon != null)
266+
{
267+
var name = arg.NameColon.Name.Identifier.Text;
268+
if (name == name1)
269+
{
270+
value1 = constantValue;
271+
}
272+
else if (name == name2)
273+
{
274+
value2 = constantValue!;
275+
}
276+
}
277+
else
278+
{
279+
if (i == 0) value1 = constantValue;
280+
else if (i == 1) value2 = constantValue;
281+
}
282+
}
283+
}
284+
}
285+
286+
static void GetArgumentConstantValues3(ArgumentListSyntax argumentListSyntax, SemanticModel model, string name1, string name2, string name3, ref object? value1, ref object? value2, ref object? value3)
287+
{
288+
var arguments = argumentListSyntax.Arguments;
289+
for (int i = 0; i < arguments.Count; i++)
290+
{
291+
var arg = arguments[i];
292+
var constant = model.GetConstantValue(arg.Expression);
293+
if (constant.HasValue)
294+
{
295+
var constantValue = constant.Value;
296+
if (arg.NameColon != null)
297+
{
298+
var name = arg.NameColon.Name.Identifier.Text;
299+
if (name == name1)
300+
{
301+
value1 = constantValue;
302+
}
303+
else if (name == name2)
304+
{
305+
value2 = constantValue!;
306+
}
307+
else if (name == name3)
308+
{
309+
value3 = constantValue!;
310+
}
311+
}
312+
else
313+
{
314+
if (i == 0) value1 = constantValue;
315+
else if (i == 1) value2 = constantValue;
316+
else if (i == 2) value3 = constantValue;
317+
}
318+
}
319+
}
320+
}
321+
259322
// GlobalOptions allow type is limited(C# compile-time constant only)
260323
// bool, char, sbyte, byte, short, ushort, int, uint, long, ulong, float, double, decimal
261324
// string

0 commit comments

Comments
 (0)