1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179
| using System.IO;
using System.Linq;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
namespace CodeTransform
{
class Program
{
static void Main(string[] args)
{
var columnName = "K_Vorname";
var oldPropertyName = "Vorname";
var newPropertyName = "FirstName";
var tableName = "Customer";
var tableDescription = "Customers";
var newPropertyDescription = "First Name";
TransformEntity("Kunde.cs", "Kunde.v2.cs", columnName, newPropertyName);
TransformConfiguration("KundeConfiguration.cs", "KundeConfiguration.v2.cs", columnName, oldPropertyName, newPropertyName);
TransformStore("KundeTableInformationStore.cs", "KundeTableInformationStore.v2.cs", tableName, tableDescription, oldPropertyName, newPropertyName, newPropertyDescription);
}
static void TransformEntity(string source, string destination, string columnName, string newPropertyName) =>
source
.Read()
.Parse()
.TransformEntity(columnName, newPropertyName)
.ToString()
.Write(destination);
static void TransformConfiguration(string source, string destination, string columnName, string oldPropertyName, string newPropertyName) =>
source
.Read()
.Parse()
.TransformConfiguration(columnName, oldPropertyName, newPropertyName)
.ToString()
.Write(destination);
static void TransformStore(string source, string destination, string tableName, string tableDescription, string oldPropertyName, string newPropertyName, string newPropertyDescription) =>
source
.Read()
.Parse()
.TransformStore(tableName, tableDescription, oldPropertyName, newPropertyName, newPropertyDescription)
.ToString()
.Write(destination);
}
static class CodeExtensions
{
internal static string Read(this string filePath) => File.ReadAllText(filePath);
internal static SyntaxTree Parse(this string code) => CSharpSyntaxTree.ParseText(code);
internal static void Write(this string code, string filePath) => File.WriteAllText(filePath, code);
#region Entity
internal static SyntaxTree TransformEntity(this SyntaxTree tree, string columnName, string newPropertyName) =>
SyntaxFactory.SyntaxTree(tree.GetRoot().TransformProperty(columnName, newPropertyName));
internal static SyntaxNode TransformProperty(this SyntaxNode node, string columnName, string newPropertyName)
{
var oldProp = node.SelectProperty(columnName);
return node.ReplaceNode(oldProp, oldProp.Transform(newPropertyName));
}
internal static PropertyDeclarationSyntax SelectProperty(this SyntaxNode node, string columnName)
{
var att = node.SelectAttributeNodeContaining(columnName);
var prop = att.Parent;
return (PropertyDeclarationSyntax)prop;
}
internal static SyntaxNode Transform(this PropertyDeclarationSyntax prop, string newPropertyName) => prop
.RemoveNode(prop.SelectAttributeNodeContaining("NotMapped"), SyntaxRemoveOptions.KeepTrailingTrivia)
.WithIdentifier(SyntaxFactory.Identifier(newPropertyName));
internal static SyntaxNode SelectAttributeNodeContaining(this SyntaxNode node, string pattern) =>
node.RecognizeAttribute(pattern) ?
node.Parent :
node.ChildNodes().Select(n => n.SelectAttributeNodeContaining(pattern)).FirstOrDefault(n => n != null);
internal static bool RecognizeAttribute(this SyntaxNode node, string pattern) =>
node.IsKind(SyntaxKind.Attribute) &&
((AttributeSyntax)node).GetText().ToString().Contains(pattern);
#endregion
#region Configuration
internal static SyntaxTree TransformConfiguration(this SyntaxTree tree, string columnName, string oldPropertyName, string newPropertyName)
{
var node = tree.GetRoot();
// try find comment
var trivia = node.SelectCommentTriviaContaining(columnName);
if (trivia.IsKind(SyntaxKind.None)) return tree;
// uncomment
var text = trivia.ToString();
var code = text.Replace("//Property", "Property").Replace("x." + oldPropertyName, "x." + newPropertyName);
var code2 = node.ToFullString().Replace(text, code);
var newTree = CSharpSyntaxTree.ParseText(code2);
return newTree;
}
internal static SyntaxTrivia SelectCommentTriviaContaining(this SyntaxNode node, string pattern) => node
.DescendantTrivia()
.Where(t => t.IsKind(SyntaxKind.SingleLineCommentTrivia))
.OfType<SyntaxTrivia>()
.Where(t => t.ToString().Contains(pattern))
.SingleOrDefault();
#endregion
#region Table
internal static SyntaxTree TransformStore(this SyntaxTree tree, string tableName, string tableDescription, string oldPropertyName, string newPropertyName, string newPropertyDescription) =>
SyntaxFactory.SyntaxTree(tree.GetRoot().TransformTable(tableName, tableDescription).TransformField(oldPropertyName, newPropertyName, newPropertyDescription));
internal static SyntaxNode TransformTable(this SyntaxNode root, string tableName, string tableDescription)
{
var method = root.DescendantNodes()
.Where(n => n.IsKind(SyntaxKind.MethodDeclaration))
.Select(n => (MethodDeclarationSyntax)n)
.FirstOrDefault(m => m.Identifier.ValueText == "GetTableAndFields");
var body = method.Body;
var init = body.DescendantNodes()
.Where(n => n.IsKind(SyntaxKind.ObjectInitializerExpression))
.Select(n => (InitializerExpressionSyntax)n)
.SingleOrDefault();
var newRoot = root.ReplaceNode(init, init.TransformAssignment("Name", tableName).TransformAssignment("Description", tableDescription));
return newRoot;
}
internal static InitializerExpressionSyntax TransformAssignment(this InitializerExpressionSyntax node, string property, string value)
{
var assignments = node.ChildNodes().OfType<AssignmentExpressionSyntax>().ToArray();
var assignment = assignments
.Where(a => a.Left.IsKind(SyntaxKind.IdentifierName))
.Where(a => ((IdentifierNameSyntax)a.Left).Identifier.ValueText == property)
.FirstOrDefault();
var newAssignment = assignment.WithRight(SyntaxFactory.LiteralExpression(SyntaxKind.StringLiteralExpression, SyntaxFactory.Literal(value)));
var newInit = node.ReplaceNode(assignment, newAssignment);
return newInit;
}
internal static SyntaxNode TransformField(this SyntaxNode root, string oldPropertyName, string newPropertyName, string newPropertyDescription)
{
var method = root.DescendantNodes()
.Where(n => n.IsKind(SyntaxKind.MethodDeclaration))
.Select(n => (MethodDeclarationSyntax)n)
.FirstOrDefault(m => m.Identifier.ValueText == "GetFieldsOnly");
var body = method.Body;
var inits = body.DescendantNodes()
.Where(n => n.IsKind(SyntaxKind.ObjectInitializerExpression))
.Select(n => (InitializerExpressionSyntax)n)
.ToArray();
var init = body.DescendantNodes()
.Where(n => n.IsKind(SyntaxKind.ObjectInitializerExpression))
.Select(n => (InitializerExpressionSyntax)n)
.FirstOrDefault(i => i.GetText().ToString().Contains(oldPropertyName));
var newRoot = root.ReplaceNode(init,
init.TransformAssignment("Name", newPropertyName).TransformAssignment("Description", newPropertyDescription).AddMapped());
return newRoot;
}
internal static InitializerExpressionSyntax AddMapped(this InitializerExpressionSyntax node)
{
var assignment = SyntaxFactory.AssignmentExpression(SyntaxKind.SimpleAssignmentExpression,
SyntaxFactory.IdentifierName("Mapped"),
SyntaxFactory.LiteralExpression(SyntaxKind.TrueLiteralExpression))
.NormalizeWhitespace();
var newNode = node.AddExpressions(assignment);
return newNode;
}
#endregion
}
} |