Skip to content

Commit

Permalink
add rootnamespace option
Browse files Browse the repository at this point in the history
  • Loading branch information
pwelter34 committed Oct 7, 2024
1 parent 1143c29 commit d6398d3
Show file tree
Hide file tree
Showing 11 changed files with 107 additions and 378 deletions.
41 changes: 4 additions & 37 deletions src/AssemblyMetadata.Generators/AssemblyConstant.cs
Original file line number Diff line number Diff line change
@@ -1,39 +1,6 @@
using System.Diagnostics.CodeAnalysis;

namespace AssemblyMetadata.Generators;

[ExcludeFromCodeCoverage]
public class AssemblyConstant : IEquatable<AssemblyConstant>
{
public AssemblyConstant(string name, string value)
{
Name = name;
Value = value;
}

public string Name { get; }

public string Value { get; }

public bool Equals(AssemblyConstant other)
{
if (ReferenceEquals(null, other))
return false;

if (ReferenceEquals(this, other))
return true;

return Name == other.Name
&& Value == other.Value;
}

public override bool Equals(object value) => value is AssemblyConstant assemblyContant && Equals(assemblyContant);

public override int GetHashCode() => HashCode.Seed.Combine(Name).Combine(Value);

public static bool operator ==(AssemblyConstant left, AssemblyConstant right) => Equals(left, right);

public static bool operator !=(AssemblyConstant left, AssemblyConstant right) => !Equals(left, right);

public override string ToString() => $"Name: {Name}; Value: {Value}";
}
public record AssemblyConstant(
string Name,
string Value
);
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
<Project>
<ItemGroup>
<CompilerVisibleProperty Include="AssemblyName" />
<CompilerVisibleProperty Include="DefineConstants" />
<CompilerVisibleProperty Include="RootNamespace" />
<CompilerVisibleProperty Include="ThisAssemblyNamespace" />
</ItemGroup>
</Project>
47 changes: 40 additions & 7 deletions src/AssemblyMetadata.Generators/AssemblyMetadataGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,14 +59,24 @@ public void Initialize(IncrementalGeneratorInitializationContext context)
var assemblyName = context.CompilationProvider
.Select(static (c, _) => c.AssemblyName);

var thisNamespace = context.AnalyzerConfigOptionsProvider
var globalOptions = context.AnalyzerConfigOptionsProvider
.Select(static (c, _) =>
{
c.GlobalOptions.TryGetValue("build_property.ThisAssemblyNamespace", out var methodName);
return methodName;
c.GlobalOptions.TryGetValue("build_property.AssemblyName", out var assemblyName);
c.GlobalOptions.TryGetValue("build_property.DefineConstants", out var defineConstants);
c.GlobalOptions.TryGetValue("build_property.RootNamespace", out var rootNamespace);
c.GlobalOptions.TryGetValue("build_property.ThisAssemblyNamespace", out var thisNamespace);
var globalOptions = new GlobalOptions(
AssemblyName: assemblyName,
DefineConstants: defineConstants,
RootNamespace: rootNamespace,
ThisAssemblyNamespace: thisNamespace);
return globalOptions;
});

var options = assemblyName.Combine(thisNamespace);
var options = assemblyName.Combine(globalOptions);

context.RegisterSourceOutput(constants.Combine(options), GenerateOutput);
}
Expand Down Expand Up @@ -127,7 +137,7 @@ private static GeneratorContext SemanticTransform(GeneratorAttributeSyntaxContex
}
}

return new GeneratorContext(Enumerable.Empty<Diagnostic>(), constants);
return new GeneratorContext([], constants);
}

private static void ReportDiagnostic(SourceProductionContext context, EquatableArray<Diagnostic> diagnostics)
Expand All @@ -136,9 +146,32 @@ private static void ReportDiagnostic(SourceProductionContext context, EquatableA
context.ReportDiagnostic(diagnostic);
}

private void GenerateOutput(SourceProductionContext context, (EquatableArray<AssemblyConstant> constants, (string? assemblyName, string? thisNamespace) options) parameters)
private void GenerateOutput(SourceProductionContext context, (EquatableArray<AssemblyConstant> constants, (string? assemblyName, GlobalOptions globalOptions) options) parameters)
{
var source = AssemblyMetadataWriter.Generate(parameters.constants, parameters.options.assemblyName, parameters.options.thisNamespace);

var constants = new List<AssemblyConstant>(parameters.constants);

if (!constants.Any(p => p.Name == nameof(GlobalOptions.AssemblyName)))
{
var assemblyName = parameters.options.globalOptions.AssemblyName ?? parameters.options.assemblyName ?? string.Empty;
constants.Add(new AssemblyConstant(nameof(GlobalOptions.AssemblyName), $"\"{assemblyName}\""));
}

if (!constants.Any(p => p.Name == nameof(GlobalOptions.DefineConstants)))
{
var defineConstants = parameters.options.globalOptions.DefineConstants;
if (!string.IsNullOrEmpty(defineConstants))
constants.Add(new AssemblyConstant(nameof(GlobalOptions.DefineConstants), $"\"{defineConstants}\""!));
}

if (!constants.Any(p => p.Name == nameof(GlobalOptions.RootNamespace)))
{
var rootNamespace = parameters.options.globalOptions.RootNamespace;
if (!string.IsNullOrEmpty(rootNamespace))
constants.Add(new AssemblyConstant(nameof(GlobalOptions.RootNamespace), $"\"{rootNamespace}\""!));
}

var source = AssemblyMetadataWriter.Generate(constants, parameters.options.globalOptions.ThisAssemblyNamespace);

context.AddSource("AssemblyMetadata.g.cs", source);
}
Expand Down
13 changes: 2 additions & 11 deletions src/AssemblyMetadata.Generators/AssemblyMetadataWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ public static class AssemblyMetadataWriter
return attribute?.InformationalVersion ?? "1.0.0.0";
});

public static string Generate(EquatableArray<AssemblyConstant> constants, string? assemblyName = null, string? thisNamespace = null)
public static string Generate(IEnumerable<AssemblyConstant> constants, string? thisNamespace = null)
{
if (constants == null)
if (constants is null)
throw new ArgumentNullException(nameof(constants));

var codeBuilder = new IndentedStringBuilder();
Expand Down Expand Up @@ -48,15 +48,6 @@ public static string Generate(EquatableArray<AssemblyConstant> constants, string
.IncrementIndent()
.AppendLine();

if (!string.IsNullOrEmpty(assemblyName))
{
codeBuilder
.Append("public const string AssemblyName = \"")
.Append(assemblyName)
.AppendLine("\";")
.AppendLine();
}

foreach (var constant in constants)
{
var name = SafeName(constant.Name);
Expand Down
79 changes: 36 additions & 43 deletions src/AssemblyMetadata.Generators/EquatableArray.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,68 +4,61 @@
namespace AssemblyMetadata.Generators;

[ExcludeFromCodeCoverage]
public readonly struct EquatableArray<T> : IReadOnlyCollection<T>, IEquatable<EquatableArray<T>>
public readonly struct EquatableArray<T> : IEquatable<EquatableArray<T>>, IEnumerable<T>
where T : IEquatable<T>
{
public static readonly EquatableArray<T> Empty = new(Array.Empty<T>());
public static readonly EquatableArray<T> Empty = new();

private readonly T[] _array;

public EquatableArray(T[] array)
{
_array = array;
}
public EquatableArray() : this([]) { }

public EquatableArray(IEnumerable<T>? array)
{
array ??= Enumerable.Empty<T>();
_array = array.ToArray();
}
public EquatableArray(T[] array) => Array = array ?? [];

public EquatableArray(IEnumerable<T> items) => Array = items.ToArray() ?? [];

public bool Equals(EquatableArray<T> array)
{
return AsSpan().SequenceEqual(array.AsSpan());
}

public override bool Equals(object obj)
public T[] Array { get; }

public int Count => Array.Length;


public ReadOnlySpan<T> AsSpan() => Array.AsSpan();

public T[] AsArray() => Array;

public T this[int i]
{
return obj is EquatableArray<T> array && Equals(this, array);
get => Array[i];
}

public static bool operator ==(EquatableArray<T> left, EquatableArray<T> right) => left.Equals(right);

public static bool operator !=(EquatableArray<T> left, EquatableArray<T> right) => !left.Equals(right);

public bool Equals(EquatableArray<T> array) => Array.AsSpan().SequenceEqual(array.AsSpan());

public override bool Equals(object? obj) => obj is EquatableArray<T> array && Equals(this, array);

public override int GetHashCode()
{
if (_array is null)
if (Array is not T[] array)
return 0;

return HashCode.Seed.CombineAll(_array);
}
var hashCode = 16777619;

public ReadOnlySpan<T> AsSpan()
{
return _array.AsSpan();
}
for (int i = 0; i < array.Length; i++)
hashCode = unchecked((hashCode * -1521134295) + EqualityComparer<T>.Default.GetHashCode(array[i]));

IEnumerator<T> IEnumerable<T>.GetEnumerator()
{
IEnumerable<T> array = _array ?? Array.Empty<T>();
return array.GetEnumerator();
return hashCode;
}

IEnumerator IEnumerable.GetEnumerator()
{
IEnumerable<T> array = _array ?? Array.Empty<T>();
return array.GetEnumerator();
}

public int Count => _array?.Length ?? 0;
IEnumerator<T> IEnumerable<T>.GetEnumerator() => (Array as IEnumerable<T>).GetEnumerator();

public static bool operator ==(EquatableArray<T> left, EquatableArray<T> right)
{
return left.Equals(right);
}
IEnumerator IEnumerable.GetEnumerator() => Array.GetEnumerator();

public static bool operator !=(EquatableArray<T> left, EquatableArray<T> right)
{
return !left.Equals(right);
}

public static implicit operator EquatableArray<T>(T[] array) => new(array);

public static implicit operator EquatableArray<T>(List<T> items) => new(items);
}
39 changes: 4 additions & 35 deletions src/AssemblyMetadata.Generators/GeneratorContext.cs
Original file line number Diff line number Diff line change
@@ -1,39 +1,8 @@
using System.Diagnostics.CodeAnalysis;

using Microsoft.CodeAnalysis;

namespace AssemblyMetadata.Generators;

[ExcludeFromCodeCoverage]
public class GeneratorContext : IEquatable<GeneratorContext>
{
public GeneratorContext(IEnumerable<Diagnostic> diagnostics, IEnumerable<AssemblyConstant> constants)
{
Diagnostics = new EquatableArray<Diagnostic>(diagnostics);
Constants = new EquatableArray<AssemblyConstant>(constants);
}

public EquatableArray<Diagnostic> Diagnostics { get; }

public EquatableArray<AssemblyConstant> Constants { get; }

public bool Equals(GeneratorContext other)
{
if (ReferenceEquals(null, other))
return false;

if (ReferenceEquals(this, other))
return true;

return Diagnostics.Equals(other.Diagnostics)
&& Constants.Equals(other.Constants);
}

public override bool Equals(object value) => value is GeneratorContext context && Equals(context);

public override int GetHashCode() => HashCode.Seed.CombineAll(Diagnostics).CombineAll(Constants);

public static bool operator ==(GeneratorContext left, GeneratorContext right) => Equals(left, right);

public static bool operator !=(GeneratorContext left, GeneratorContext right) => !Equals(left, right);
}
public record GeneratorContext(
EquatableArray<Diagnostic> Diagnostics,
EquatableArray<AssemblyConstant> Constants
);
8 changes: 8 additions & 0 deletions src/AssemblyMetadata.Generators/GlobalOptions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace AssemblyMetadata.Generators;

public record GlobalOptions(
string? AssemblyName,
string? DefineConstants,
string? RootNamespace,
string? ThisAssemblyNamespace
);
Loading

0 comments on commit d6398d3

Please sign in to comment.