Skip to content

Commit d0a11a7

Browse files
committed
Allow setting visibility and switching to static readonly props
Setting the `ThisAssembly` class to public should be somewhat rare, but might be desirable in some cases. When the class is made public, there's a surprising "bug" in that updating the assembly providing the `ThisAssembly` class will *not* cause another assembly consuming its values to reflect the changes. This is because the compiler will efectively inline the constants, so effectively every call site has a copy of the value. This is somewhat unintuitive, but it's perfectly sensible when the use is for internal purposes. The new ThisAssemblyVisibility=public property allows both setting the generated class visibility to and switching (for constants) to static properties. For ThisAssembly.Strings and ThisAssembly.Resources, only the class visibility is changed. Fixes #64
1 parent 9f77b87 commit d0a11a7

File tree

14 files changed

+102
-28
lines changed

14 files changed

+102
-28
lines changed

src/ThisAssembly.Constants/CSharp.sbntxt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,13 @@
4141
{{- remarks -}}
4242
{{ obsolete }}
4343
{{~ if RawStrings && value.IsText ~}}
44-
public const string {{ value.Name | string.replace "-" "_" | string.replace " " "_" }} =
44+
public {{ Modifier }} string {{ value.Name | string.replace "-" "_" | string.replace " " "_" }} ={{ Lambda }}
4545

4646
"""
4747
{{ value.Value }}
4848
""";
4949
{{~ else ~}}
50-
public const {{ value.Type }} {{ value.Name | string.replace "-" "_" | string.replace " " "_" }} =
50+
public {{ Modifier }} {{ value.Type }} {{ value.Name | string.replace "-" "_" | string.replace " " "_" }} ={{ Lambda }}
5151
{{~ if value.IsText ~}}
5252
@"{{ value.Value }}";
5353
{{~ else ~}}
@@ -71,7 +71,7 @@ namespace {{ Namespace }};
7171
/// <summary>
7272
/// Provides access to the current assembly information.
7373
/// </summary>
74-
partial class ThisAssembly
74+
{{ Visibility }}partial class ThisAssembly
7575
{
7676
/// <summary>
7777
/// Provides access project-defined constants.

src/ThisAssembly.Constants/ConstantsGenerator.cs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,10 @@ public void Initialize(IncrementalGeneratorInitializationContext context)
5858

5959
// Read the ThisAssemblyNamespace property or default to null
6060
var right = context.AnalyzerConfigOptionsProvider
61-
.Select((c, t) => c.GlobalOptions.TryGetValue("build_property.ThisAssemblyNamespace", out var ns) && !string.IsNullOrEmpty(ns) ? ns : null)
61+
.Select((c, t) => (
62+
c.GlobalOptions.TryGetValue("build_property.ThisAssemblyNamespace", out var ns) && !string.IsNullOrEmpty(ns) ? ns : null,
63+
c.GlobalOptions.TryGetValue("build_property.ThisAssemblyVisibility", out var visibility) && !string.IsNullOrEmpty(visibility) ? visibility : null
64+
))
6265
.Combine(context.ParseOptionsProvider);
6366

6467
var inputs = files.Combine(right);
@@ -69,9 +72,9 @@ public void Initialize(IncrementalGeneratorInitializationContext context)
6972
}
7073

7174
void GenerateConstant(SourceProductionContext spc,
72-
(((string name, string value, string? type, string? comment, string root), (string? ns, ParseOptions parse)), StatusOptions options) args)
75+
(((string name, string value, string? type, string? comment, string root), ((string? ns, string? visibility), ParseOptions parse)), StatusOptions options) args)
7376
{
74-
var (((name, value, type, comment, root), (ns, parse)), options) = args;
77+
var (((name, value, type, comment, root), ((ns, visibility), parse)), options) = args;
7578
var cs = (CSharpParseOptions)parse;
7679

7780
if (!string.IsNullOrWhiteSpace(ns) &&
@@ -94,7 +97,7 @@ void GenerateConstant(SourceProductionContext spc,
9497
// For now, we only support C# though
9598
var file = parse.Language.Replace("#", "Sharp") + ".sbntxt";
9699
var template = Template.Parse(EmbeddedResource.GetContent(file), file);
97-
var model = new Model(rootArea, ns);
100+
var model = new Model(rootArea, ns, "public".Equals(visibility, StringComparison.OrdinalIgnoreCase));
98101
if ((int)cs.LanguageVersion >= 1100)
99102
model.RawStrings = true;
100103

src/ThisAssembly.Constants/Model.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,16 @@
99
namespace ThisAssembly;
1010

1111
[DebuggerDisplay("Values = {RootArea.Values.Count}")]
12-
record Model(Area RootArea, string? Namespace)
12+
record Model(Area RootArea, string? Namespace, bool IsPublic)
1313
{
1414
public bool RawStrings { get; set; } = false;
1515
public string Version => Assembly.GetExecutingAssembly().GetName().Version.ToString(3);
1616
public string Url => Devlooped.Sponsors.SponsorLink.Funding.HelpUrl;
1717
public string? Warn { get; set; }
1818
public string? Remarks { get; set; }
19+
public string Visibility => IsPublic ? "public " : "";
20+
public string Modifier => IsPublic ? "static" : "const";
21+
public string Lambda => IsPublic ? ">" : "";
1922
}
2023

2124
[DebuggerDisplay("Name = {Name}, NestedAreas = {NestedAreas.Count}, Values = {Values.Count}")]

src/ThisAssembly.Constants/ThisAssembly.Constants.targets

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
<ItemGroup>
55
<CompilerVisibleProperty Include="ThisAssemblyNamespace" />
6+
<CompilerVisibleProperty Include="ThisAssemblyVisibility" />
67

78
<CompilerVisibleItemMetadata Include="Constant" MetadataName="ItemType" />
89
<CompilerVisibleItemMetadata Include="Constant" MetadataName="Comment" />

src/ThisAssembly.Resources/CSharp.sbntxt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ namespace {{ Namespace }};
5252
/// <summary>
5353
/// Provides access to the current assembly information.
5454
/// </summary>
55-
partial class ThisAssembly
55+
{{ Visibility }}partial class ThisAssembly
5656
{
5757
/// <summary>
5858
/// Provides access to assembly resources.

src/ThisAssembly.Resources/Model.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,10 @@
77
namespace ThisAssembly;
88

99
[DebuggerDisplay("Values = {RootArea.Values.Count}")]
10-
record Model(Area RootArea, string? Namespace)
10+
record Model(Area RootArea, string? Namespace, bool IsPublic)
1111
{
1212
public string Version => Assembly.GetExecutingAssembly().GetName().Version.ToString(3);
13+
public string Visibility => IsPublic ? "public " : "";
1314
}
1415

1516
[DebuggerDisplay("Name = {Name}")]

src/ThisAssembly.Resources/ResourcesGenerator.cs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,10 @@ public void Initialize(IncrementalGeneratorInitializationContext context)
4747

4848
// Read the ThisAssemblyNamespace property or default to null
4949
var right = context.AnalyzerConfigOptionsProvider
50-
.Select((c, t) => c.GlobalOptions.TryGetValue("build_property.ThisAssemblyNamespace", out var ns) && !string.IsNullOrEmpty(ns) ? ns : null);
50+
.Select((c, t) => (
51+
c.GlobalOptions.TryGetValue("build_property.ThisAssemblyNamespace", out var ns) && !string.IsNullOrEmpty(ns) ? ns : null,
52+
c.GlobalOptions.TryGetValue("build_property.ThisAssemblyVisibility", out var visibility) && !string.IsNullOrEmpty(visibility) ? visibility : null
53+
));
5154

5255
context.RegisterSourceOutput(
5356
files.Combine(right),
@@ -56,9 +59,9 @@ public void Initialize(IncrementalGeneratorInitializationContext context)
5659

5760
static void GenerateSource(SourceProductionContext spc,
5861
((ImmutableArray<(string resourceName, string? kind, string? comment)> files,
59-
ImmutableArray<string> extensions), string? ns) args)
62+
ImmutableArray<string> extensions), (string? ns, string? visibility)) args)
6063
{
61-
var ((files, extensions), ns) = args;
64+
var ((files, extensions), (ns, visibility)) = args;
6265

6366
var file = "CSharp.sbntxt";
6467
var template = Template.Parse(EmbeddedResource.GetContent(file), file);
@@ -87,7 +90,7 @@ static void GenerateSource(SourceProductionContext spc,
8790
.ToList();
8891

8992
var root = Area.Load(basePath, resources);
90-
var model = new Model(root, ns);
93+
var model = new Model(root, ns, "public".Equals(visibility, StringComparison.OrdinalIgnoreCase));
9194

9295
var output = template.Render(model, member => member.Name);
9396

src/ThisAssembly.Resources/readme.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,15 @@ treated as a text file:
4343
You can also add a `Comment` item metadata attribute, which will be used as the `<summary>` XML
4444
doc for the generated member.
4545

46+
## Customizing the generated code
47+
48+
The following MSBuild properties can be used to customize the generated code:
49+
50+
| Property | Description |
51+
|-------------------------|------------------------------------------------------------------------------------------------------|
52+
| ThisAssemblyNamespace | Sets the namespace of the generated `ThisAssembly` root class. If not set, it will be in the global namespace. |
53+
| ThisAssemblyVisibility | Sets the visibility modifier of the generated `ThisAssembly` root class. If not set, it will be internal. |
54+
4655
<!-- #resources -->
47-
<!-- include ../visibility.md -->
4856
<!-- include https://github.com/devlooped/sponsors/raw/main/footer.md -->
4957
<!-- exclude -->

src/ThisAssembly.Strings/CSharp.sbntxt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ namespace {{ Namespace }};
8686
/// <summary>
8787
/// Provides access to the current assembly information.
8888
/// </summary>
89-
partial class ThisAssembly
89+
{{ Visibility }}partial class ThisAssembly
9090
{
9191
/// <summary>
9292
/// Provides access to the assembly strings.

src/ThisAssembly.Strings/Model.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,13 @@
77
using System.Xml.Linq;
88

99
[DebuggerDisplay("ResourceName = {ResourceName}, Values = {RootArea.Values.Count}")]
10-
record Model(ResourceArea RootArea, string ResourceName, string? Namespace)
10+
record Model(ResourceArea RootArea, string ResourceName, string? Namespace, bool IsPublic)
1111
{
1212
public string? Version => Assembly.GetExecutingAssembly().GetName().Version?.ToString(3);
1313
public string Url => Devlooped.Sponsors.SponsorLink.Funding.HelpUrl;
1414
public string? Warn { get; set; }
1515
public string? Remarks { get; set; }
16+
public string Visibility => IsPublic ? "public " : "";
1617
}
1718

1819
static class ResourceFile

0 commit comments

Comments
 (0)