Created
October 5, 2014 11:22
-
-
Save threecourse/2c2c612646b492ae24bd to your computer and use it in GitHub Desktop.
analyze codes with roslyn
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Text; | |
using System.Threading.Tasks; | |
using Microsoft.CodeAnalysis; | |
using Microsoft.CodeAnalysis.CSharp; | |
using Microsoft.CodeAnalysis.CSharp.Syntax; | |
namespace MyRoslyn.CSharp | |
{ | |
class Program | |
{ | |
static void MainCSharp(string[] args) | |
{ | |
// ソリューションを取得し、そこからComplilationを取得する。 | |
var ws = Microsoft.CodeAnalysis.MSBuild.MSBuildWorkspace.Create(); | |
var sol = ws.OpenSolutionAsync(@"C:\Users\Administrator2\Documents\Visual Studio 14\Projects\RoslynTarget\RoslynTarget.sln").Result; | |
var proj = sol.Projects.First(); | |
var comp = proj.GetCompilationAsync().Result; | |
// Compilationから情報を解析する。 | |
GetMethodsClass.Analyze(comp); | |
Console.Read(); | |
} | |
} | |
public class GetMethodsClass | |
{ | |
public static void Analyze(Compilation comp) | |
{ | |
// ファイルごとにSyntaxTreeが分かれているので、各SyntaxTreeごとに処理する。 | |
foreach (var tree in comp.SyntaxTrees) | |
{ | |
Console.WriteLine("================================================"); | |
Console.WriteLine(tree.FilePath); | |
Console.WriteLine("------------------------------------------------"); | |
var model = comp.GetSemanticModel(tree); | |
var root = tree.GetRoot(); | |
// Method宣言を表すノードを取得し、各ノードごとに処理する。 | |
var methods = root.DescendantNodes().OfType<MethodDeclarationSyntax>(); | |
foreach (MethodDeclarationSyntax methodDeclareNode in methods) | |
{ | |
// Methodの情報を取得する。 | |
var symbol = model.GetDeclaredSymbol(methodDeclareNode); | |
Console.WriteLine(symbol.ToDisplayString()); | |
Console.WriteLine("----"); | |
// 代入を表すノードを判定するためのメソッドを作成する。 | |
SyntaxKind[] AssignKinds = new SyntaxKind[] | |
{ SyntaxKind.AddAssignmentExpression, | |
SyntaxKind.AndAssignmentExpression, | |
SyntaxKind.SimpleAssignmentExpression, | |
SyntaxKind.SimpleAssignmentExpression , | |
SyntaxKind.AddAssignmentExpression , | |
SyntaxKind.SubtractAssignmentExpression , | |
SyntaxKind.MultiplyAssignmentExpression , | |
SyntaxKind.DivideAssignmentExpression , | |
SyntaxKind.ModuloAssignmentExpression , | |
SyntaxKind.AndAssignmentExpression , | |
SyntaxKind.ExclusiveOrAssignmentExpression , | |
SyntaxKind.OrAssignmentExpression , | |
SyntaxKind.LeftShiftAssignmentExpression , | |
SyntaxKind.RightShiftAssignmentExpression}; | |
Func<SyntaxKind, bool> isTargetSyntax = (SyntaxKind syntaxKind) => (Array.IndexOf(AssignKinds, syntaxKind) >= 0); | |
// 代入を表すノードを取得し、各ノードごとに処理する。 | |
var assignnodes = methodDeclareNode.DescendantNodes().OfType<BinaryExpressionSyntax>().Where(exp => isTargetSyntax(exp.CSharpKind())); | |
foreach (BinaryExpressionSyntax assignNode in assignnodes) | |
{ | |
// 代入式の左辺を取得する。 | |
var left = assignNode.Left; | |
Console.WriteLine("{0} --- {1}", left.ToString(), assignNode.ToString()); | |
// 代入式の左辺からWalkerで情報を取得する。 | |
var walker = new GetSymbolWalker { SemanticModel = model }; | |
walker.Visit(left); | |
Console.WriteLine(walker.Results); | |
} | |
Console.WriteLine(); | |
} | |
Console.WriteLine("================================================"); | |
Console.WriteLine(); | |
} | |
} | |
} | |
// ノードに含まれるSymbolを取得し、情報を書き出す。 | |
// FAQ(10)を参照 | |
public class GetSymbolWalker : CSharpSyntaxWalker | |
{ | |
public SemanticModel SemanticModel { get; set; } | |
public StringBuilder Results { get; private set; } | |
public GetSymbolWalker() | |
{ | |
Results = new StringBuilder(); | |
} | |
public override void Visit(SyntaxNode node) | |
{ | |
if (node is IdentifierNameSyntax) | |
{ | |
var symbol = SemanticModel.GetSymbolInfo(node).Symbol; | |
var type = SemanticModel.GetTypeInfo(node).Type; | |
if (type != null) | |
{ | |
Results.Append(symbol.ToDisplayString()); | |
Results.Append(" : "); | |
Results.Append(type.ToDisplayString()); | |
Results.AppendLine(); | |
} | |
} | |
base.Visit(node); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment