private static IEnumerable <string> CreateClassMethodInfoOutput(ClassMethodInfo info, string sourceFilePath) { List <string> result = new List <string>(); if (info.Children != null && info.Children.Any()) { foreach (ClassMethodInfo child in info.Children) { string line = sourceFilePath + "\t" + info.MethodName + "\t" + child.MethodName + "\t" + info.LineCount; result.Add(line); result.AddRange(CreateClassMethodInfoOutput(child, sourceFilePath)); } } else if (info.LineCount > 0) { result.Add(sourceFilePath + "\t" + info.MethodName + "\t\t" + info.LineCount); } return(result); }
public static bool IsEquals(ClassMethodInfo c1, ClassMethodInfo c2) => c1.ClassName == c2.ClassName && c1.MethodName == c2.MethodName;
/// <summary> /// 一つのメソッド呼び出し結果を出力 /// </summary> /// <param name="methodBlock">呼び出し元のメソッド定義</param> /// <param name="model">セマンティックモデル</param> /// <param name="thisNameSpace">呼び出し元クラスの属する名前空間</param> /// <param name="thisClassName">呼び出し元クラス名</param> /// <param name="indent">インデント(省略可能)</param> private static IEnumerable <ClassMethodInfo> GetCallingMethods(IEnumerable <SyntaxNode> calling, SemanticModel model, string thisNameSpace, string thisClassName) { List <ClassMethodInfo> result = new List <ClassMethodInfo>(); foreach (SyntaxNode node in calling) { if (node is IdentifierNameSyntax ident) { var symbol = model.GetSymbolInfo(ident).Symbol; if (symbol == null) { continue; } if (symbol.Kind != SymbolKind.Method) { continue; } string nameSpace = symbol.ContainingNamespace.ToString(); if (nameSpace == "System") { continue; } if (_exceptNamespacesStartsWith.Any(s => nameSpace.StartsWith(s))) { continue; } ClassMethodInfo cmi = new ClassMethodInfo(); cmi.ClassName = symbol.ContainingType.ToString(); cmi.MethodName = symbol.OriginalDefinition.ToString(); if (cmi.MethodName.Contains("DoApplicationLogic")) { // プロジェクトの特有処理。メソッド名をすり替える cmi.MethodName = cmi.MethodName.Replace("DoApplicationLogic", "DoMain"); } if (cmi.MethodName.Contains("DoBusinessLogic")) { // プロジェクトの特有処理。メソッド名をすり替える cmi.MethodName = cmi.MethodName.Replace("DoBusinessLogic", "DoMain"); } result.Add(cmi); } else if (node is ObjectCreationExpressionSyntax objCreate) { var symbol = model.GetSymbolInfo(objCreate).Symbol; if (symbol != null) { string nameSpace = symbol.ContainingNamespace.ToString(); if (nameSpace == "System") { continue; } if (_exceptNamespacesStartsWith.Any(s => nameSpace.StartsWith(s))) { continue; } ClassMethodInfo cmi = new ClassMethodInfo(); cmi.ClassName = symbol.ContainingType.ToString(); cmi.MethodName = symbol.OriginalDefinition.ToString(); result.Add(cmi); } else { // ここに入ってきた時の対処法が分からない } } } return(result); }
/// <summary> /// 一つのメソッド定義を解析 /// </summary> /// <param name="methodBlock">メソッド定義</param> /// <param name="model">セマンティックモデル</param> /// <param name="nameSpace">呼び出し元クラスの属する名前空間</param> /// <param name="className">呼び出し元クラス名</param> /// <param name="indent">インデント(省略可能)</param> private static ClassMethodInfo GetMethodDeclaration(MethodDeclarationSyntax methodBlock, SemanticModel model, string nameSpace, string className) { StringBuilder str = new StringBuilder(); try { var symbol = model.GetDeclaredSymbol(methodBlock); str.Append("Method Declaration: "); str.Append("\t"); if (symbol != null) { str.Append(symbol.ContainingType); } else { str.Append(nameSpace + "." + className); } str.Append("\t"); str.Append(methodBlock.Identifier.Text); str.Append(methodBlock.ParameterList); str.Append("\t"); string modifier = methodBlock.Modifiers.ToString(); str.Append(modifier); str.Append("\t"); int lineCount = 0; using (StringReader sReader = new StringReader(methodBlock.WithoutTrivia().ToFullString())) { string line; while ((line = sReader.ReadLine()) != null) { if (line != string.Empty && !string.IsNullOrWhiteSpace(line) && !line.Trim().StartsWith("//")) { lineCount++; } } } str.Append(lineCount); //Console.WriteLine((indent ?? string.Empty) + str); IEnumerable <ClassMethodInfo> children = GetCallingMethods(methodBlock, model, nameSpace, className); ClassMethodInfo result = new ClassMethodInfo(); result.ClassName = symbol.ContainingType.ToString(); result.MethodName = symbol.OriginalDefinition.ToString(); result.LineCount = lineCount; result.Children.AddRange(children); return(result); } catch (Exception ex) { List <string> errorReport = new List <string>(); errorReport.Add($"AnalyzingNamespace: {nameSpace}"); errorReport.Add($"AnalyzingClass: {className}"); errorReport.Add($"AnalyzingMethod: {methodBlock.Identifier.Text}"); WriteExceptionLog(new ApplicationException("[" + string.Join(",", errorReport) + "]", ex)); } return(null); }
/// <summary> /// 一つのクラスを解析 /// </summary> /// <param name="cls">クラス定義</param> /// <param name="model">セマンティックモデル</param> /// <param name="indent">インデント(省略可能)</param> private static IEnumerable <ClassMethodInfo> GetClassDeclaration(ClassDeclarationSyntax cls, SemanticModel model, string sourceFilePath) { string nameSpace = string.Empty; string className = string.Empty; ClassDeclarationSyntax tmp = cls; while (tmp.Parent is ClassDeclarationSyntax syntax1) { className = tmp.Identifier.Text; nameSpace = string.IsNullOrEmpty(nameSpace) ? className : className + "." + nameSpace; tmp = syntax1; } if (cls.Parent is NamespaceDeclarationSyntax syntax2) { nameSpace = syntax2.Name.ToString() + nameSpace; } else { nameSpace = "(名前空間無し)"; } try { List <ClassMethodInfo> list = new List <ClassMethodInfo>(); var constructorBlocks = cls.DescendantNodes().OfType <ConstructorDeclarationSyntax>(); foreach (ConstructorDeclarationSyntax constructorBlock in constructorBlocks) { if (sourceFilePath.ToLower().EndsWith(".designer.cs")) { continue; } ClassMethodInfo con = GetConstructorDeclaration(constructorBlock, model, nameSpace, cls.Identifier.Text); list.Add(con); } var methodBlocks = cls.DescendantNodes().OfType <MethodDeclarationSyntax>(); foreach (MethodDeclarationSyntax methodBlock in methodBlocks) { if (sourceFilePath.ToLower().EndsWith(".designer.cs") && methodBlock.Identifier.ToString() != "InitializeComponent") { continue; } ClassMethodInfo method = GetMethodDeclaration(methodBlock, model, nameSpace, cls.Identifier.Text); if (methodBlock.Identifier.ToString() == "InitializeComponent") { // InitializeComponentはカウントしない。 method.LineCount = 0; } list.Add(method); } return(list); } catch (Exception ex) { List <string> errorReport = new List <string>(); errorReport.Add($"AnalyzingNamespace: {nameSpace}"); errorReport.Add($"AnalyzingClass: {className}"); WriteExceptionLog(new ApplicationException("[" + string.Join(",", errorReport) + "]", ex)); } return(null); }