diff --git a/src/ThisAssembly.Constants/ConstantsGenerator.cs b/src/ThisAssembly.Constants/ConstantsGenerator.cs
index 1c15ed7c..2fcb9046 100644
--- a/src/ThisAssembly.Constants/ConstantsGenerator.cs
+++ b/src/ThisAssembly.Constants/ConstantsGenerator.cs
@@ -3,6 +3,7 @@
using System.IO;
using System.Linq;
using System.Text;
+using System.Text.RegularExpressions;
using Devlooped.Sponsors;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
@@ -16,6 +17,8 @@ namespace ThisAssembly;
[Generator(LanguageNames.CSharp)]
public class ConstantsGenerator : IIncrementalGenerator
{
+ static readonly Regex SeeExpr = new("", RegexOptions.Compiled);
+
public void Initialize(IncrementalGeneratorInitializationContext context)
{
var files = context.AdditionalTextsProvider
@@ -121,12 +124,16 @@ void GenerateConstant(SourceProductionContext spc,
// structures via functions.
if (parse.Language == LanguageNames.CSharp)
{
- output = SyntaxFactory.ParseCompilationUnit(output, options: cs)
+ output = SeeExpr.Replace(SyntaxFactory
+ .ParseCompilationUnit(output, options: cs)
.NormalizeWhitespace()
.GetText()
- .ToString();
+ .ToString(),
+ $"");
}
spc.AddSource($"{root}.{name}.g.cs", SourceText.From(output, Encoding.UTF8));
}
+
+
}
diff --git a/src/ThisAssembly.Resources/CSharp.sbntxt b/src/ThisAssembly.Resources/CSharp.sbntxt
index 419a262c..82b9c55d 100644
--- a/src/ThisAssembly.Resources/CSharp.sbntxt
+++ b/src/ThisAssembly.Resources/CSharp.sbntxt
@@ -57,5 +57,16 @@ namespace {{ Namespace }};
///
/// Provides access to assembly resources.
///
+ {{~ if Remarks ~}}
+ {{ Remarks }}
+ ///
+ {{~ end ~}}
+ {{~ if Warn ~}}
+ [Obsolete("{{ Warn }}", false
+ #if NET6_0_OR_GREATER
+ , UrlFormat = "{{ Url }}"
+ #endif
+ )]
+ {{~ end ~}}
{{ render RootArea }}
}
diff --git a/src/ThisAssembly.Resources/Model.cs b/src/ThisAssembly.Resources/Model.cs
index d2e69139..4652e2af 100644
--- a/src/ThisAssembly.Resources/Model.cs
+++ b/src/ThisAssembly.Resources/Model.cs
@@ -9,6 +9,9 @@ namespace ThisAssembly;
[DebuggerDisplay("Values = {RootArea.Values.Count}")]
record Model(Area RootArea, string? Namespace, bool IsPublic)
{
+ public string? Warn { get; set; }
+ public string? Remarks { get; set; }
+ public string Url => Devlooped.Sponsors.SponsorLink.Funding.HelpUrl;
public string Version => Assembly.GetExecutingAssembly().GetName().Version.ToString(3);
public string Visibility => IsPublic ? "public " : "";
}
diff --git a/src/ThisAssembly.Resources/ResourcesGenerator.cs b/src/ThisAssembly.Resources/ResourcesGenerator.cs
index 8e2ff04a..7b5ce772 100644
--- a/src/ThisAssembly.Resources/ResourcesGenerator.cs
+++ b/src/ThisAssembly.Resources/ResourcesGenerator.cs
@@ -1,17 +1,24 @@
using System;
using System.Collections.Immutable;
+using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
+using System.Text.RegularExpressions;
+using Devlooped.Sponsors;
using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.Text;
using Scriban;
+using static Devlooped.Sponsors.SponsorLink;
namespace ThisAssembly;
[Generator(LanguageNames.CSharp)]
public class ResourcesGenerator : IIncrementalGenerator
{
+ static readonly Regex SeeExpr = new("", RegexOptions.Compiled);
+
public void Initialize(IncrementalGeneratorInitializationContext context)
{
context.RegisterPostInitializationOutput(
@@ -52,16 +59,19 @@ public void Initialize(IncrementalGeneratorInitializationContext context)
c.GlobalOptions.TryGetValue("build_property.ThisAssemblyVisibility", out var visibility) && !string.IsNullOrEmpty(visibility) ? visibility : null
));
+ // this is required to ensure status is registered properly independently of analyzer runs.
+ var options = context.GetStatusOptions();
+
context.RegisterSourceOutput(
- files.Combine(right),
+ files.Combine(right).Combine(options.Combine(context.ParseOptionsProvider)),
GenerateSource);
}
static void GenerateSource(SourceProductionContext spc,
- ((ImmutableArray<(string resourceName, string? kind, string? comment)> files,
- ImmutableArray extensions), (string? ns, string? visibility)) args)
+ (((ImmutableArray<(string resourceName, string? kind, string? comment)> files,
+ ImmutableArray extensions), (string? ns, string? visibility)), (StatusOptions options, ParseOptions parse)) args)
{
- var ((files, extensions), (ns, visibility)) = args;
+ var (((files, extensions), (ns, visibility)), (options, parse)) = args;
var file = "CSharp.sbntxt";
var template = Template.Parse(EmbeddedResource.GetContent(file), file);
@@ -70,6 +80,23 @@ static void GenerateSource(SourceProductionContext spc,
.GroupBy(f => Path.Combine(
Path.GetDirectoryName(f.resourceName),
Path.GetFileNameWithoutExtension(f.resourceName)));
+
+ string? warn = default;
+ string? remarks = default;
+ if (IsEditor)
+ {
+ var status = Diagnostics.GetOrSetStatus(options);
+ if (status == SponsorStatus.Unknown || status == SponsorStatus.Expired)
+ {
+ warn = string.Format(CultureInfo.CurrentCulture, Resources.Editor_Disabled, Funding.Product, Funding.HelpUrl);
+ remarks = Resources.Editor_DisabledRemarks;
+ }
+ else if (status == SponsorStatus.Grace && Diagnostics.TryGet() is { } grace && grace.Properties.TryGetValue(nameof(SponsorStatus.Grace), out var days))
+ {
+ remarks = string.Format(CultureInfo.CurrentCulture, Resources.Editor_GraceRemarks, days);
+ }
+ }
+
foreach (var group in groupsWithoutExtensions)
{
var basePath = group.Key;
@@ -90,16 +117,19 @@ static void GenerateSource(SourceProductionContext spc,
.ToList();
var root = Area.Load(basePath, resources);
- var model = new Model(root, ns, "public".Equals(visibility, StringComparison.OrdinalIgnoreCase));
-
+ var model = new Model(root, ns, "public".Equals(visibility, StringComparison.OrdinalIgnoreCase))
+ {
+ Warn = warn,
+ Remarks = remarks,
+ };
var output = template.Render(model, member => member.Name);
- // Apply formatting since indenting isn't that nice in Scriban when rendering nested
- // structures via functions.
- output = Microsoft.CodeAnalysis.CSharp.SyntaxFactory.ParseCompilationUnit(output)
+ output = SeeExpr.Replace(SyntaxFactory
+ .ParseCompilationUnit(output, options: parse as CSharpParseOptions)
.NormalizeWhitespace()
.GetText()
- .ToString();
+ .ToString(),
+ $"");
spc.AddSource(
$"{basePath.Replace('\\', '.').Replace('/', '.')}.g.cs",
diff --git a/src/ThisAssembly.Resources/ThisAssembly.Resources.props b/src/ThisAssembly.Resources/ThisAssembly.Resources.props
index 16795a20..ca8ce68b 100644
--- a/src/ThisAssembly.Resources/ThisAssembly.Resources.props
+++ b/src/ThisAssembly.Resources/ThisAssembly.Resources.props
@@ -1,7 +1,7 @@
- .txt|.cs|.sql|.json|.md
+ .txt|.cs|.sql|.json|.md|.resx
diff --git a/src/ThisAssembly.Strings/StringsGenerator.cs b/src/ThisAssembly.Strings/StringsGenerator.cs
index 5bf298e3..7c4fdebb 100644
--- a/src/ThisAssembly.Strings/StringsGenerator.cs
+++ b/src/ThisAssembly.Strings/StringsGenerator.cs
@@ -2,8 +2,8 @@
using System.Globalization;
using System.IO;
using System.Linq;
-using System.Resources;
using System.Text;
+using System.Text.RegularExpressions;
using Devlooped.Sponsors;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
@@ -16,6 +16,8 @@ namespace ThisAssembly;
[Generator(LanguageNames.CSharp)]
public class StringsGenerator : IIncrementalGenerator
{
+ static readonly Regex SeeExpr = new("", RegexOptions.Compiled);
+
public void Initialize(IncrementalGeneratorInitializationContext context)
{
// Read the ThisAssemblyNamespace property or default to null
@@ -83,10 +85,12 @@ static void GenerateSource(SourceProductionContext spc,
var output = template.Render(model, member => member.Name);
- output = SyntaxFactory.ParseCompilationUnit(output, options: parse as CSharpParseOptions)
+ output = SeeExpr.Replace(SyntaxFactory
+ .ParseCompilationUnit(output, options: parse as CSharpParseOptions)
.NormalizeWhitespace()
.GetText()
- .ToString();
+ .ToString(),
+ $"");
spc.AddSource(resourceName, SourceText.From(output, Encoding.UTF8));
}