ExampleSourceGenerator.cs 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. using Microsoft.CodeAnalysis;
  2. using Microsoft.CodeAnalysis.CSharp.Syntax;
  3. using Microsoft.CodeAnalysis.Text;
  4. using System.Collections.Generic;
  5. using System.Diagnostics;
  6. using System.IO;
  7. using System.Linq;
  8. using System.Text;
  9. namespace SourceGen
  10. {
  11. [Generator]
  12. public class ExampleSourceGenerator : ISourceGenerator
  13. {
  14. public void Execute(GeneratorExecutionContext context)
  15. {
  16. //Debugger.Launch();
  17. var assemblies = context.Compilation.SourceModule.ReferencedAssemblySymbols.ToArray();
  18. var flag = assemblies.Any(v => v.Name == "UnityEngine");
  19. var types = assemblies.SelectMany(a =>
  20. {
  21. try
  22. {
  23. var main = a.Identity.Name.Split('.').Aggregate(a.GlobalNamespace, (s, c) => s.GetNamespaceMembers().Single(m => m.Name.Equals(c)));
  24. return GetAllTypes(main);
  25. }
  26. catch
  27. {
  28. return Enumerable.Empty<ITypeSymbol>();
  29. }
  30. }).ToArray();
  31. types = types.Where(t => t.TypeKind == TypeKind.Interface && t.DeclaredAccessibility == Accessibility.Public)
  32. .Where(v => v.AllInterfaces.Any(d => d.Name == "IProtocol")).ToArray();
  33. var code = @"#nullable disable
  34. using System;
  35. using System.Runtime.Serialization;
  36. namespace SourceGen
  37. {
  38. #content
  39. }
  40. ";
  41. var str = "";
  42. foreach (var model in types)
  43. {
  44. str += "\n[DataContract]";
  45. str += $"\npublic struct {model.Name}Data:{model.ContainingNamespace}.{model.Name}";
  46. str += "\n{";
  47. var i = 0;
  48. foreach (var member in model.GetMembers())
  49. {
  50. if (member is IPropertySymbol p)
  51. {
  52. str += $"\n [DataMember(Order = {i})]";
  53. str += $"\n public {p.Type} {p.Name}{{get;set;}}";
  54. i++;
  55. }
  56. }
  57. str += "\n}";
  58. }
  59. code = code.Replace("#content", str);
  60. context.AddSource("Structs.cs", SourceText.From(code, Encoding.UTF8));
  61. }
  62. public void Initialize(GeneratorInitializationContext context)
  63. {
  64. //context.RegisterForSyntaxNotifications(() => new CustomSyntaxReceiver());
  65. }
  66. private static IEnumerable<ITypeSymbol> GetAllTypes(INamespaceSymbol root)
  67. {
  68. foreach (var namespaceOrTypeSymbol in root.GetMembers())
  69. {
  70. if (namespaceOrTypeSymbol is INamespaceSymbol @namespace)
  71. {
  72. foreach (var nested in GetAllTypes(@namespace))
  73. yield return nested;
  74. }
  75. else if (namespaceOrTypeSymbol is ITypeSymbol type)
  76. yield return type;
  77. }
  78. }
  79. }
  80. internal class CustomSyntaxReceiver : ISyntaxReceiver
  81. {
  82. public List<InterfaceDeclarationSyntax> Models { get; } = new List<InterfaceDeclarationSyntax>();
  83. public void OnVisitSyntaxNode(SyntaxNode syntaxNode)
  84. {
  85. //Debugger.Launch();
  86. if (syntaxNode.ToString().Contains("IStation520"))
  87. {
  88. }
  89. return;
  90. if (syntaxNode is InterfaceDeclarationSyntax it)
  91. {
  92. if (it.BaseList.Types.Any(v => v.Type.ToString() == "IProtocol"))
  93. {
  94. Models.Add(it);
  95. }
  96. }
  97. }
  98. }
  99. public class myReceiver : SourceReferenceResolver
  100. {
  101. public override bool Equals(object other)
  102. {
  103. throw new System.NotImplementedException();
  104. }
  105. public override int GetHashCode()
  106. {
  107. throw new System.NotImplementedException();
  108. }
  109. public override string NormalizePath(string path, string baseFilePath)
  110. {
  111. throw new System.NotImplementedException();
  112. }
  113. public override Stream OpenRead(string resolvedPath)
  114. {
  115. throw new System.NotImplementedException();
  116. }
  117. public override string ResolveReference(string path, string baseFilePath)
  118. {
  119. throw new System.NotImplementedException();
  120. }
  121. }
  122. }