From aea91825d8bff1bcf2707ab38689239e8b98656e Mon Sep 17 00:00:00 2001 From: neuecc Date: Thu, 14 Mar 2024 18:42:54 +0900 Subject: [PATCH] All diagnostics --- .../BlazorApp1/Components/Pages/Home.razor.cs | 3 +- sandbox/ConsoleApp1/Program.cs | 14 ++ .../DiagnosticDescriptors.cs | 8 + src/Claudia.FunctionGenerator/Parser.cs | 19 +- src/Claudia/Constants.cs | 9 +- .../DiagnosticsTest.cs | 227 ++++++++++++++++++ .../UnitTest1.cs | 10 - 7 files changed, 268 insertions(+), 22 deletions(-) create mode 100644 tests/Claudia.FunctionGenerator.Tests/DiagnosticsTest.cs delete mode 100644 tests/Claudia.FunctionGenerator.Tests/UnitTest1.cs diff --git a/sandbox/BlazorApp1/Components/Pages/Home.razor.cs b/sandbox/BlazorApp1/Components/Pages/Home.razor.cs index 9683fdd..7f327e5 100644 --- a/sandbox/BlazorApp1/Components/Pages/Home.razor.cs +++ b/sandbox/BlazorApp1/Components/Pages/Home.razor.cs @@ -16,7 +16,7 @@ public partial class Home bool running = false; - async void SendClick() + async Task SendClick() { if (running) return; if (string.IsNullOrWhiteSpace(textInput)) return; @@ -53,7 +53,6 @@ async void SendClick() finally { running = false; - StateHasChanged(); } } } \ No newline at end of file diff --git a/sandbox/ConsoleApp1/Program.cs b/sandbox/ConsoleApp1/Program.cs index bb4de4f..cdb13ef 100644 --- a/sandbox/ConsoleApp1/Program.cs +++ b/sandbox/ConsoleApp1/Program.cs @@ -2,6 +2,7 @@ using System; using System.Linq; using System.Net.Http; +using System.Net.NetworkInformation; using System.Text; using System.Threading.Tasks; using System.Xml; @@ -348,6 +349,19 @@ static async Task GetHtmlFromWeb(string url) using var client = new HttpClient(); return await client.GetStringAsync(url); } + + ///// + ///// demo + ///// + ///// t + ///// g + ///// o + ///// + //[ClaudiaFunction] + //static int Demo(TimeSpan ts, Guid guid, DateTimeOffset dtofset) + //{ + // return 0; + //} } diff --git a/src/Claudia.FunctionGenerator/DiagnosticDescriptors.cs b/src/Claudia.FunctionGenerator/DiagnosticDescriptors.cs index 5770006..c818298 100644 --- a/src/Claudia.FunctionGenerator/DiagnosticDescriptors.cs +++ b/src/Claudia.FunctionGenerator/DiagnosticDescriptors.cs @@ -77,4 +77,12 @@ internal static class DiagnosticDescriptors category: Category, defaultSeverity: DiagnosticSeverity.Error, isEnabledByDefault: true); + + public static readonly DiagnosticDescriptor VoidReturnIsNotSupported = new( + id: "CLFG010", + title: "void return type is not supported", + messageFormat: "The '{0}' method return void or Task or ValueTask there are not supported, allows T, Task or ValueTask", + category: Category, + defaultSeverity: DiagnosticSeverity.Error, + isEnabledByDefault: true); } diff --git a/src/Claudia.FunctionGenerator/Parser.cs b/src/Claudia.FunctionGenerator/Parser.cs index 2d592ce..4c31088 100644 --- a/src/Claudia.FunctionGenerator/Parser.cs +++ b/src/Claudia.FunctionGenerator/Parser.cs @@ -104,6 +104,7 @@ internal ParseResult[] Parse() } } + var hasError = false; foreach (var p in method.Parameters) { // castable types @@ -126,12 +127,26 @@ internal ParseResult[] Parse() case SpecialType.System_DateTime: break; default: - // TODO: support DateTimeOffset, Guid, TimeSpan and there nullable. - // TODO: void is not allowed. + if (p.Type.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat) is "global::System.DateTimeOffset" or "global::System.Guid" or "global::System.TimeSpan") + { + break; + } + + hasError = true; context.ReportDiagnostic(Diagnostic.Create(DiagnosticDescriptors.ParameterTypeIsNotSupported, method.Locations[0], method.Name, p.Name, p.Type.Name)); continue; } } + if (hasError) + { + continue; + } + + if (method.ReturnsVoid || (method.ReturnType.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat) is "global::System.Threading.Tasks.Task" or "global::System.Threading.Tasks.ValueTask")) + { + context.ReportDiagnostic(Diagnostic.Create(DiagnosticDescriptors.VoidReturnIsNotSupported, method.Locations[0], method.Name)); + continue; + } methods.Add(new Method { Symbol = method, Syntax = (MethodDeclarationSyntax)source.TargetNode }); } diff --git a/src/Claudia/Constants.cs b/src/Claudia/Constants.cs index f5bb17d..78f75ba 100644 --- a/src/Claudia/Constants.cs +++ b/src/Claudia/Constants.cs @@ -68,20 +68,13 @@ public static class SystemPrompts { // https://twitter.com/AmandaAskell/status/1765207842993434880 public const string Claude3 = """ -The assistant is Claude, created by Anthropic. The current date is March 4th, 2024. - +The assistant is Claude, created by Anthropic. Claude's knowledge base was last updated on August 2023. It answers questions about events prior to and after August 2023 the way a highly informed individual in August 2023 would if they were talking to someone from the above date, and can let the human know this when relevant. - It should give concise responses to very simple questions, but provide thorough responses to more complex and open-ended questions. - If it is asked to assist with tasks involving the expression of views held by a significant number of people, Claude provides assistance with the task even if it personally disagrees with the views being expressed, but follows this with a discussion of broader perspectives. - Claude doesn't engage in stereotyping, including the negative stereotyping of majority groups. - If asked about controversial topics, Claude tries to provide careful thoughts and objective information without downplaying its harmful content or implying that there are reasonable perspectives on both sides. - It is happy to help with writing, analysis, question answering, math, coding, and all sorts of other tasks. It uses markdown for coding. - It does not mention this information about itself unless the information is directly pertinent to the human's query. """; } \ No newline at end of file diff --git a/tests/Claudia.FunctionGenerator.Tests/DiagnosticsTest.cs b/tests/Claudia.FunctionGenerator.Tests/DiagnosticsTest.cs new file mode 100644 index 0000000..3aa6b55 --- /dev/null +++ b/tests/Claudia.FunctionGenerator.Tests/DiagnosticsTest.cs @@ -0,0 +1,227 @@ +namespace Claudia.FunctionGenerator.Tests; + +public class DiagnosticsTest +{ + public class GeneratorDiagnosticsTest(ITestOutputHelper output) + { + void Compile(int id, string code, bool allowMultipleError = false) + { + var diagnostics = CSharpGeneratorRunner.RunGenerator(code); + + // ignore CS0759: No defining declaration found for implementing declaration of partial method 'method'. + // ignore CS8795: Partial method 'method' must have an implementation part because it has accessibility modifiers. + diagnostics = diagnostics.Where(x => x.Id != "CS0759" && x.Id != "CS8795").ToArray(); + + foreach (var item in diagnostics) + { + output.WriteLine(item.ToString()); + } + + if (!allowMultipleError) + { + diagnostics.Length.Should().Be(1); + diagnostics[0].Id.Should().Be("CLFG" + id.ToString("000")); + } + else + { + diagnostics.Select(x => x.Id).Should().Contain("CLFG" + id.ToString("000")); + } + } + + [Fact] + public void CLFG001_MuestBePartial() + { + Compile(1, """ +using Claudia; + +public static class Hoge +{ + [ClaudiaFunction] + public static int Method(int x) => x; +} +"""); + } + + [Fact] + public void CLFG002_NestedNotAllow() + { + Compile(2, """ +using Claudia; + +public static partial class Hoge +{ + public static partial class Fuga + { + [ClaudiaFunction] + public static int Method(int x) => x; + } +} +"""); + } + + [Fact] + public void CLFG003_GenericTypeNotSupported() + { + Compile(3, """ +using Claudia; + +public static partial class Hoge +{ + [ClaudiaFunction] + public static int Method(int x) => x; +} +"""); + } + + [Fact] + public void CLFG004_MustBeStatic() + { + Compile(4, """ +using Claudia; + +public partial class Hoge +{ + [ClaudiaFunction] + public static int Method(int x) => x; +} +"""); + } + + [Fact] + public void CLFG005_MethodNeedsDocumentationCommentXml() + { + Compile(5, """ +using Claudia; + +public static partial class Hoge +{ + [ClaudiaFunction] + public static int Method(int x) => x; +} +"""); + } + + [Fact] + public void CLFG006_MethodNeedsSummary() + { + Compile(6, """ +using Claudia; + +public static partial class Hoge +{ + /// + /// + /// + /// X1 + [ClaudiaFunction] + public static int Method(int x) => x; +} +"""); + } + + [Fact] + public void CLFG007_ParameterNeedsDescription() + { + Compile(7, """ +using Claudia; + +public static partial class Hoge +{ + /// + /// Foo + /// + /// + [ClaudiaFunction] + public static int Method(int x) => x; +} +""", true); + } + + [Fact] + public void CLFG008_AllParameterNeedsDescription() + { + Compile(8, """ +using Claudia; + +public static partial class Hoge +{ + /// + /// Foo + /// + [ClaudiaFunction] + public static int Method(int x) => x; +} +""", true); + } + + [Fact] + public void CLFG009_ParameterTypeIsNotSupported() + { + // void return + Compile(9, """ +using Claudia; + +public static partial class Hoge +{ + /// + /// Foo + /// + /// X2 + [ClaudiaFunction] + public static int Method(System.Exception x) => 0; +} +"""); + } + + [Fact] + public void CLFG010_VoidReturnIsNotSupported() + { + Compile(10, """ +using Claudia; + +public static partial class Hoge +{ + /// + /// Foo + /// + /// X2 + [ClaudiaFunction] + public static void Method1(int x){ } +} +"""); + + Compile(10, """ +using Claudia; +using System.Threading.Tasks; + +public static partial class Hoge +{ + /// + /// Foo + /// + /// X2 + [ClaudiaFunction] + public static Task Method2(int x) => Task.CompletedTask; +} +"""); + + Compile(10, """ +using Claudia; +using System.Threading.Tasks; + +public static partial class Hoge +{ + /// + /// Foo + /// + /// X2 + [ClaudiaFunction] + public static ValueTask Method3(int x) => ValueTask.CompletedTask; +} +"""); + + + + } + } +} diff --git a/tests/Claudia.FunctionGenerator.Tests/UnitTest1.cs b/tests/Claudia.FunctionGenerator.Tests/UnitTest1.cs deleted file mode 100644 index cefdd61..0000000 --- a/tests/Claudia.FunctionGenerator.Tests/UnitTest1.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace Claudia.FunctionGenerator.Tests; - -public class UnitTest1 -{ - [Fact] - public void Test1() - { - - } -} \ No newline at end of file