Skip to content

Instantly share code, notes, and snippets.

@kyubuns
Created November 28, 2017 07:29
Show Gist options
  • Save kyubuns/947185c50bd1db08068716b8f2053509 to your computer and use it in GitHub Desktop.
Save kyubuns/947185c50bd1db08068716b8f2053509 to your computer and use it in GitHub Desktop.
MessagePack-CSharpで[MessagePackObject(true)]してたのを展開するやつ
using System;
using System.IO;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
namespace MessagePackIikanzi
{
public static class Program
{
public static void Main(string[] args)
{
var sourceFileName = args[0];
var text = File.ReadAllText(sourceFileName);
var csharpParseOptions = new CSharpParseOptions(
LanguageVersion.CSharp6,
DocumentationMode.Parse,
SourceCodeKind.Regular, new List<string> {"UNITY_EDITOR", "UNITY_IOS", "UNITY_ANDROID"});
var tree = CSharpSyntaxTree.ParseText(text, csharpParseOptions);
var myWriter = new ClassRewriter();
var newRoot = myWriter.Visit(tree.GetRoot());
File.WriteAllText(sourceFileName, newRoot.ToFullString(), Encoding.UTF8);
}
}
}
public class ClassRewriter : CSharpSyntaxRewriter
{
public override SyntaxNode VisitClassDeclaration(ClassDeclarationSyntax node)
{
var newNode = node;
Console.WriteLine($"- VisitClassDeclaration: {node.Identifier}");
var attribute = node.AttributeLists.SelectMany(x => x.Attributes).FirstOrDefault(x => x.Name.ToFullString() == "MessagePackObject");
if (attribute != null)
{
if (attribute.ToFullString().Contains("true"))
{
var newAttribute = SyntaxFactory.Attribute(SyntaxFactory.IdentifierName("MessagePackObject"), null);
newNode = node.ReplaceNode(attribute, newAttribute);
return base.VisitClassDeclaration(new MemberRewriter(node.Identifier.ToFullString()).Visit(newNode) as ClassDeclarationSyntax);
}
}
return base.VisitClassDeclaration(newNode);
}
}
public class MemberRewriter : CSharpSyntaxRewriter
{
private readonly string ClassName;
private int i;
public MemberRewriter(string className)
{
ClassName = className;
}
public override SyntaxNode VisitPropertyDeclaration(PropertyDeclarationSyntax node)
{
var newNode = node;
if ((node.Parent as ClassDeclarationSyntax).Identifier.ToFullString() != ClassName) return base.VisitPropertyDeclaration(newNode);
if (node.Modifiers.Any(x => x.Kind() != SyntaxKind.PublicKeyword)) return base.VisitPropertyDeclaration(newNode);
if (node.AttributeLists.SelectMany(x => x.Attributes).Any(x => x.Name.ToFullString() == "IgnoreMember")) return base.VisitPropertyDeclaration(newNode);
Console.WriteLine($" - VisitPropertyDeclaration: {node}");
var attribute = SyntaxFactory.AttributeList(
SyntaxFactory.SingletonSeparatedList(
SyntaxFactory.Attribute(SyntaxFactory.IdentifierName("Key"),
SyntaxFactory.ParseAttributeArgumentList($"({i})")
)));
var newField = node.WithAttributeLists(node.AttributeLists.Add(attribute));
newNode = node.ReplaceNode(node, newField);
i++;
return base.VisitPropertyDeclaration(newNode);
}
public override SyntaxNode VisitFieldDeclaration(FieldDeclarationSyntax node)
{
var newNode = node;
if ((node.Parent as ClassDeclarationSyntax).Identifier.ToFullString() != ClassName) return base.VisitFieldDeclaration(newNode);
if (node.Modifiers.Any(x => x.Kind() != SyntaxKind.PublicKeyword)) return base.VisitFieldDeclaration(newNode);
if (node.AttributeLists.SelectMany(x => x.Attributes).Any(x => x.Name.ToFullString() == "IgnoreMember")) return base.VisitFieldDeclaration(newNode);
Console.WriteLine($" - VisitFieldDeclaration: {node}");
var attribute = SyntaxFactory.AttributeList(
SyntaxFactory.SingletonSeparatedList(
SyntaxFactory.Attribute(SyntaxFactory.IdentifierName("Key"),
SyntaxFactory.ParseAttributeArgumentList($"({i})")
)));
var newField = node.WithAttributeLists(node.AttributeLists.Add(attribute));
newNode = node.ReplaceNode(node, newField);
i++;
return base.VisitFieldDeclaration(newNode);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment