diff --git a/README.md b/README.md index 9b4928e..bdf648c 100644 --- a/README.md +++ b/README.md @@ -149,13 +149,13 @@ Must.BeTrue(!list.Contains(x)); // ✅ Prefer: Must.HaveSameSequence(expectedLi ## 🧭 `FUnit.Directives` -With FUnit.Directives package, you can *include* external file into file-based app project by adding special directive comment `//:funit:include `. +With FUnit.Directives package, you can *include* external file into file-based app project by adding special directive `#warning funit include `. ```cs #:package FUnit@* #:package FUnit.Directives@* -//:funit:include ./path/to/external-file.cs +#warning funit include ./path/to/external-file.cs return FUnit.Run( /* tests depending on 'external-file.cs */ ); ``` diff --git a/directives/FUnitSourceGenerator.cs b/directives/FUnitSourceGenerator.cs index 322b9a0..aab5702 100644 --- a/directives/FUnitSourceGenerator.cs +++ b/directives/FUnitSourceGenerator.cs @@ -57,12 +57,12 @@ public void Execute(GeneratorExecutionContext context) foreach (var syntaxTree in context.Compilation.SyntaxTrees) { var root = syntaxTree.GetCompilationUnitRoot(); - var comments = root + var directives = root .DescendantTrivia() - .Where(t => t.IsKind(SyntaxKind.SingleLineCommentTrivia)) + .Where(t => t.IsKind(SyntaxKind.WarningDirectiveTrivia)) .ToList(); // ToList is better than ToImmutableList in this case - foreach (var trivia in comments) + foreach (var trivia in directives) { if (trivia.SyntaxTree is null) { @@ -72,26 +72,32 @@ public void Execute(GeneratorExecutionContext context) continue; } - if (!trivia.ToString().StartsWith(SR.DirectivePrefix, StringComparison.Ordinal)) + // Check for no indentation + var line = trivia.GetLocation().GetLineSpan().StartLinePosition.Character; + if (line != 0) { continue; } - // Check for no indentation - var line = trivia.GetLocation().GetLineSpan().StartLinePosition.Character; - if (line != 0) + var fullText = trivia.ToString(); + if (!fullText.StartsWith("#warning", StringComparison.Ordinal)) { continue; } - var fullText = trivia.ToString().TrimEnd(); + // 8 is the length of "#warning" + var textAfterWarning = fullText.Substring(8).TrimStart(); + if (!textAfterWarning.StartsWith(SR.DirectivePrefix, StringComparison.Ordinal)) + { + continue; + } #if DEBUG context.ReportDiagnostic( - Diagnostic.Create(SR.DebugDiagnostic, trivia.GetLocation(), fullText)); + Diagnostic.Create(SR.DebugDiagnostic, trivia.GetLocation(), fullText.TrimEnd())); #endif - var keywordAndArgs = fullText.Substring(SR.DirectivePrefix.Length); + var keywordAndArgs = textAfterWarning.Substring(SR.DirectivePrefix.Length); var parts = keywordAndArgs.Split(SR.DirectiveSeparators, 2, StringSplitOptions.RemoveEmptyEntries); var keyword = parts.FirstOrDefault()?.Trim() ?? string.Empty; diff --git a/directives/SR.cs b/directives/SR.cs index 3f21f25..b009535 100644 --- a/directives/SR.cs +++ b/directives/SR.cs @@ -9,10 +9,10 @@ namespace FUnit.Directives { internal class SR { - public const string DirectivePrefix = "//:funit:"; + public const string DirectivePrefix = "funit"; public const string DiagnosticCategory = nameof(FUnit); - public static readonly char[] DirectiveSeparators = new[] { ' ' }; + public static readonly char[] DirectiveSeparators = new[] { ' ', '\t' }; public static readonly char[] InvalidChars = new[] { '/', '\\', ':' }; // File.Exists will reject invalid path so remove only directory separators public static DiagnosticDescriptor MissingFileNameDiagnostic = new( diff --git a/sandbox/Sandbox.cs b/sandbox/Sandbox.cs index 8e7542f..e4debac 100644 --- a/sandbox/Sandbox.cs +++ b/sandbox/Sandbox.cs @@ -13,28 +13,28 @@ /* uncomment to test FUnit.Directives // multiple include of same file should be allowed -//:funit:include Sandbox.cs -//:funit:include Sandbox.cs -//:funit:include ./Sandbox.cs -//:funit:include ./Sandbox.cs - -// IGNORED: prefix must be single line comment and placed at line beginning -// //:funit: -///:funit: +#warning funit include Sandbox.cs +#warning funit include Sandbox.cs +#warning funit include ./Sandbox.cs +#warning funit include ./Sandbox.cs + +// IGNORED: prefix must be #warning funit and placed at line beginning +// #warning funit +//#warning funit // leading space is not allowed - //:funit: + #warning funit // ERRORS -//:funit:include -//:funit:include NotFound.cs -//:funit:unknown -//:funit: -//:funit:include file not supported +#warning funit include +#warning funit include NotFound.cs +#warning funit unknown +#warning funit +#warning funit include file not supported */ // IGNORED: in multiline comment /* -//:funit: +#warning funit */ diff --git a/test/Directives_test.cs b/test/Directives_test.cs index 7682053..dacb849 100644 --- a/test/Directives_test.cs +++ b/test/Directives_test.cs @@ -1,15 +1,19 @@ #:project ../src #:package FUnit.Directives@* +#if true +return 0; +#else + // cannot...? --> #:project ../directives // [TEST] allow multiple include directives scattered in project -//:funit:include Directives_TestClass.cs -//:funit:include Directives_TestClass.cs +#warning funit include Directives_TestClass.cs +#warning funit include Directives_TestClass.cs // [TEST] no duplicate even if same file is specified in different way -//:funit:include ./Directives_TestClass.cs -//:funit:include ./Directives_TestClass.cs +#warning funit include ./Directives_TestClass.cs +#warning funit include ./Directives_TestClass.cs #warning THIS WARNING IS EMITTED BY PREPROCESSOR DIRECTIVE @@ -17,9 +21,11 @@ { describe("FUnit.Directives", it => { - it("should work (:funit:include)", () => + it("should work (#warning funit include)", () => { Must.BeEqual(310, Tests.TestClass.TestMethod()); }); }); }); + +#endif