diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2ff6da7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.vs/ +[Bb]in/ +[Oo]bj/ diff --git a/src/Geis.ScratchApp/Geis.ScratchApp.csproj b/src/Geis.ScratchApp/Geis.ScratchApp.csproj new file mode 100644 index 0000000..e432de9 --- /dev/null +++ b/src/Geis.ScratchApp/Geis.ScratchApp.csproj @@ -0,0 +1,17 @@ + + + + Exe + net7.0 + enable + enable + + + + + + + + diff --git a/src/Geis.ScratchApp/Program.cs b/src/Geis.ScratchApp/Program.cs new file mode 100644 index 0000000..667291c --- /dev/null +++ b/src/Geis.ScratchApp/Program.cs @@ -0,0 +1,5 @@ +using Geis; + +var collection = new ValueParserCollection(); +collection.AddDefaultParser(); +collection.AddDefaultParser(); diff --git a/src/Geis.ValueParserGenerators/DefaultValueParserGenerator.cs b/src/Geis.ValueParserGenerators/DefaultValueParserGenerator.cs new file mode 100644 index 0000000..69a9d7e --- /dev/null +++ b/src/Geis.ValueParserGenerators/DefaultValueParserGenerator.cs @@ -0,0 +1,49 @@ +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using System.Collections.Immutable; + +namespace Geis.ValueParserGenerators; + +[Generator] +public class DefaultValueParserGenerator : IIncrementalGenerator +{ + public void Initialize(IncrementalGeneratorInitializationContext context) + { + //System.Diagnostics.Debugger.Launch(); + + var provider = context + .SyntaxProvider + .CreateSyntaxProvider( + predicate: (c, _) => c is GenericNameSyntax n, + transform: (n, _) => (GenericNameSyntax)n.Node) + .Where(x => x is not null); + + var compilation = context.CompilationProvider.Combine(provider.Collect()); + + context.RegisterSourceOutput( + compilation, + (spc, source) => Execute(spc, source.Left, source.Right)); + } + + private void Execute( + SourceProductionContext context, + Compilation compilation, + ImmutableArray genericNames) + { + foreach (var name in genericNames) + { + // todo: add explicitly constructor value parsers that reference the TryParse or new(string) member of T. + + context.ReportDiagnostic( + Diagnostic.Create( + new DiagnosticDescriptor( + id: "GVPG0001", + title: "Possible Reference To AddDefaultParser", + messageFormat: "Found a possible reference to the AddDefaultParser method.", + category: "Accomplishment", + defaultSeverity: DiagnosticSeverity.Warning, + isEnabledByDefault: true), + name.GetLocation())); + } + } +} diff --git a/src/Geis.ValueParserGenerators/Geis.ValueParserGenerators.csproj b/src/Geis.ValueParserGenerators/Geis.ValueParserGenerators.csproj new file mode 100644 index 0000000..f8e9e10 --- /dev/null +++ b/src/Geis.ValueParserGenerators/Geis.ValueParserGenerators.csproj @@ -0,0 +1,17 @@ + + + + netstandard2.0 + latest + true + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + diff --git a/src/Geis.sln b/src/Geis.sln new file mode 100644 index 0000000..1f6ed85 --- /dev/null +++ b/src/Geis.sln @@ -0,0 +1,37 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.31903.59 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Geis.ValueParserGenerators", "Geis.ValueParserGenerators\Geis.ValueParserGenerators.csproj", "{388C1697-D0ED-4340-AE58-22CF614FD50D}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Geis", "Geis\Geis.csproj", "{8B1B4AA8-17E8-4A0C-946B-FD975A2598EA}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Geis.ScratchApp", "Geis.ScratchApp\Geis.ScratchApp.csproj", "{435D5879-9BB7-4106-BB3A-2B22750C08EF}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {388C1697-D0ED-4340-AE58-22CF614FD50D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {388C1697-D0ED-4340-AE58-22CF614FD50D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {388C1697-D0ED-4340-AE58-22CF614FD50D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {388C1697-D0ED-4340-AE58-22CF614FD50D}.Release|Any CPU.Build.0 = Release|Any CPU + {8B1B4AA8-17E8-4A0C-946B-FD975A2598EA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8B1B4AA8-17E8-4A0C-946B-FD975A2598EA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8B1B4AA8-17E8-4A0C-946B-FD975A2598EA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8B1B4AA8-17E8-4A0C-946B-FD975A2598EA}.Release|Any CPU.Build.0 = Release|Any CPU + {435D5879-9BB7-4106-BB3A-2B22750C08EF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {435D5879-9BB7-4106-BB3A-2B22750C08EF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {435D5879-9BB7-4106-BB3A-2B22750C08EF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {435D5879-9BB7-4106-BB3A-2B22750C08EF}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {3043616A-5042-4512-816E-3345E1FA7AB3} + EndGlobalSection +EndGlobal diff --git a/src/Geis/Geis.csproj b/src/Geis/Geis.csproj new file mode 100644 index 0000000..ad4f58d --- /dev/null +++ b/src/Geis/Geis.csproj @@ -0,0 +1,9 @@ + + + + net7 + enable + enable + + + diff --git a/src/Geis/ValueParserCollection.cs b/src/Geis/ValueParserCollection.cs new file mode 100644 index 0000000..b68b971 --- /dev/null +++ b/src/Geis/ValueParserCollection.cs @@ -0,0 +1,17 @@ +namespace Geis; + +public class ValueParserCollection +{ + private readonly Dictionary> _parsers = new(); + + public ValueParserCollection SetParser(Func parser) where T : notnull + { + _parsers[typeof(T)] = s => parser(s); + return this; + } +} + +public static class ValueParserCollectionExtensions +{ + public static ValueParserCollection AddDefaultParser(this ValueParserCollection collection) => collection; +}