public static ImmutableDictionary <TypeName, JsonType> GetJsonTypes(ImmutableArray <SyntaxTree> nodes, Compilation compilation) { var walker = new JsonAttributeScanningWalker(compilation); foreach (var tinyType in TinyTypeScanningWalker.GetTinyTypes(compilation, nodes)) { walker.VisitTinyType(tinyType); } foreach (var node in nodes) { walker.Visit(node.GetRoot()); } return(walker.JsonTypes.ToImmutable()); }
public static string Generate(string outputPath, ImmutableArray <SyntaxTree> syntaxTrees, Compilation compilation) { var tinyTypes = TinyTypeScanningWalker.GetTinyTypes(compilation, syntaxTrees); using (var outputFile = new FileStream(Path.Combine(outputPath, "TinyTypes.cs"), FileMode.Create, FileAccess.Write)) using (var writer = new StreamWriter(outputFile, leaveOpen: true)) { writer.WriteLine("using System;"); writer.WriteLine("using System.Diagnostics;"); writer.WriteLine("using System.Collections.Generic;"); writer.WriteLine("using System.Globalization;"); writer.WriteLine(); writer.WriteLine("#pragma warning disable CA2225 // Provide method alternative to op_Explicit"); writer.WriteLine(); foreach (var ns in tinyTypes.GroupBy(tt => tt.Namespace)) { writer.WriteLine(); writer.WriteLine($"namespace {ns.Key}"); writer.WriteLine("{"); foreach (var tinyType in ns) { writer.WriteLine(); writer.WriteLine(@"[DebuggerDisplay(""{value,nq}"")]"); writer.WriteLine($"readonly partial struct {tinyType.Type.ShortName} : IEquatable<{tinyType.Type.ShortName}>"); writer.WriteLine("{"); writer.WriteLine($"private readonly {tinyType.InnerType} value;"); writer.WriteLine(); writer.WriteLine($"public {tinyType.Type.ShortName}({tinyType.InnerType} value)"); writer.WriteLine("{"); writer.WriteLine("this.value = value;"); writer.WriteLine("}"); writer.WriteLine(); writer.WriteLine($"public static explicit operator {tinyType.InnerType}({tinyType.Type.ShortName} domainId) => domainId.value;"); writer.WriteLine($"public static explicit operator {tinyType.Type.ShortName}({tinyType.InnerType} value) => new {tinyType.Type.ShortName}(value);"); writer.WriteLine(); if (tinyType.InnerType.IsNumericType) { writer.WriteLine($"public override string ToString() => value.ToString(CultureInfo.InvariantCulture);"); } else { writer.WriteLine($"public override string ToString() => value.ToString();"); } writer.WriteLine(); writer.WriteLine($"public bool Equals({tinyType.Type.ShortName} other) => value.Equals(other.value);"); writer.WriteLine($"public override bool Equals(object? obj) => obj is {tinyType.Type.ShortName} other && Equals(other);"); writer.WriteLine(); if (tinyType.InnerType.IsNumericType) { writer.WriteLine($"public override int GetHashCode() => value;"); } else { writer.WriteLine($"public override int GetHashCode() => value.GetHashCode();"); } writer.WriteLine(); writer.WriteLine($"public static bool operator ==({tinyType.Type.ShortName} left, {tinyType.Type.ShortName} right) => left.Equals(right);"); writer.WriteLine($"public static bool operator !=({tinyType.Type.ShortName} left, {tinyType.Type.ShortName} right) => !left.Equals(right);"); writer.WriteLine(); writer.WriteLine($"public static IEqualityComparer<{tinyType.Type.ShortName}> EqualityComparer {{ get; }} = new ValueEqualityComparer();"); writer.WriteLine($"private sealed class ValueEqualityComparer : IEqualityComparer<{tinyType.Type.ShortName}>"); writer.WriteLine("{"); writer.WriteLine($"public bool Equals({tinyType.Type.ShortName} x, {tinyType.Type.ShortName} y) => x.Equals(y);"); writer.WriteLine($"public int GetHashCode({tinyType.Type.ShortName} obj) => obj.GetHashCode();"); writer.WriteLine("}"); writer.WriteLine("}"); } writer.WriteLine("}"); } return(outputFile.Name); } }