/// <summary> /// Return all CustomTypes that are nested within this CustomType /// </summary> private CustomType[] FindNestedCustomTypes() { CustomType[] nested; Type[] nestedTypes = assemblyType.GetNestedTypes(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static); if (nestedTypes.Length > 0) { nested = new CustomType[nestedTypes.Length]; for (int i = 0; i < nestedTypes.Length; i++) { Type currentType = nestedTypes[i]; string simplifiedName = SimplifyTypeFullName(currentType); CustomType customType = DependencyAnalyzer.GetCustomTypeFromString(simplifiedName); if (customType != null) { nested[i] = customType; } else { Debug.LogError("!! COULD NOT FIND " + simplifiedName + " in CustomType lookup table. Abort!"); } } } //Else no nested types found, so init empty array else { nested = new CustomType[0]; } return(nested); }
private void OnEnable() { if (window == null) { Init(); } depAnalyzer = new DependencyAnalyzer(); gitAnalyzer = new GitAnalyzer(); verticalSplitView.splitNormalizedPosition = 0.2f; // Create shortened names for commit messages, shown in drop-down menu commitNames = new string[gitAnalyzer.commitList.Count + 1]; commitNames[0] = "NOTHING SELECTED"; for (int i = 0; i < gitAnalyzer.commitList.Count; i++) { LibGit2Sharp.Commit c = gitAnalyzer.commitList[i]; string commitName = (i + 1) + ": [" + c.Author.When.DateTime.ToString("g") + "] (" + c.Author.Name + "): " + c.Message; commitName = commitName.Replace("/", "-"); // The EditorGUILayout.PopUp uses '/' to branch the selection, which I dont want commitName = commitName.Replace("\n", " "); // Newlines cause subsequent options to be pushed down, which I dont want commitName = commitName.Substring(0, Mathf.Min(100, commitName.Length)) + "..."; commitNames[i + 1] = commitName; } commitIndex = 0; typeIndex = 0; hideUnchanged = false; ResetTree(); }
void ResetTree(bool keepIndicesSame = false) { if (style != null) { style.fontSize = defaultFontSize; } // Reset vars to default values selectedNode = null; tempSelectedNode = null; isFirstFrameDrawn = true; maxNodesPerLevel = 0; totalChangesInTree = 0; maxImpactStrength = 0; yPad = 0; zoomLevel = 0; scrollPosition = Vector2.zero; // Recreate the global data structures allNodes = new Dictionary <int, LinkedList <CustomTypeNode> >(); allFiles = new HashSet <CustomFile>(); // Find the CustomType selected from the drop-down menu Dictionary <string, CustomType> .ValueCollection customTypes = depAnalyzer.GetAllCustomTypes(); typeNames = new string[customTypes.Count]; CustomType chosenType = null; int i = 0; foreach (CustomType t in customTypes) { if (i == typeIndex) { chosenType = DependencyAnalyzer.GetCustomTypeFromString(t.simplifiedFullName); } typeNames[i] = t.simplifiedFullName + " (in file: " + t.file + ")"; i++; } // Populate the allNodes data structure, using the chosenType as the starting point CreateDependencyTree(chosenType, null, new LinkedList <CustomType>(), 0); // Calculate the maximum number of nodes at any level of the tree foreach (KeyValuePair <int, LinkedList <CustomTypeNode> > pair in allNodes) { if (pair.Value.Count > maxNodesPerLevel) { maxNodesPerLevel = pair.Value.Count; } } }
/// <summary> /// Determine if the matched type has any parents. If so, create the text that should be prepended /// onto the given type to match the format used in the customTypeLookup from DependencyAnalyzer. /// E.g. if B is not nested, return an empty string. If B is nested in A, return "A+". /// If C is nested in B which is nested in A, return "A+B+". /// </summary> private string FindParentTypesInText(CustomType previousType, int startLineNum, int endLineNum) { System.Text.StringBuilder typeString = new System.Text.StringBuilder(); // Handle nested types (e.g. private classes nested in other classes, potentially many nested levels) bool foundParent = false; do { // No outer type detected, i.e. match is not nested if (previousType == null) { foundParent = true; } //Check if match is nested in previous matched type else if (startLineNum >= previousType.startLineNum && endLineNum <= previousType.endLineNum) { Type parent = previousType.assemblyType; while (parent.IsNested) { typeString.Insert(0, parent.Name + "+"); parent = parent.DeclaringType; } typeString.Insert(0, parent.Name + "+"); foundParent = true; } //Not nested in previous matched type. Check if nested in that type's parent (if it exists) else { if (previousType.assemblyType.DeclaringType != null) { previousType = DependencyAnalyzer.GetCustomTypeFromString(CustomType.SimplifyTypeFullName(previousType.assemblyType.DeclaringType)); } else { previousType = null; } } } while (!foundParent); return(typeString.ToString()); }
public List <CustomType> MatchTypesInFile(CustomFile file) { List <CustomType> typesInFile = new List <CustomType>(); // Remove comments and strings to ensure no false positive matches string text = RemoveCommentsAndStrings(file); int currentLineNum = 1; int currentIndex = 0; // Index of text string where current match begins CustomType previousType = null; // Keep track of the previous match's type // Iterate through all class declarations found in the file code foreach (Match typeMatch in typeRegex.Matches(text)) { //Keep track of current line number by counting newlines since the last match currentLineNum += text.Substring(currentIndex, typeMatch.Index - currentIndex).Count(x => x == '\n'); currentIndex = typeMatch.Index; // Find the start and end lines of the matched type int startLineNum = currentLineNum; int endLineNum = FindEndLineNum(typeMatch.Index, currentLineNum, text); // Get the name of the type as it appears in the text System.Text.StringBuilder typeString = new System.Text.StringBuilder(""); typeString.Append(typeMatch.Groups["type"].Captures[0].Value); // Prepend type string with any of its parents (e.g. if B is nested in A, then string becomes "A+B") typeString.Insert(0, FindParentTypesInText(previousType, startLineNum, endLineNum)); // Get the CustomType associated with the string found in text (modified if type was nested to match desired format of key) CustomType currentType = DependencyAnalyzer.GetCustomTypeFromString(typeString.ToString()); if (currentType == null) { Debug.LogError("Could not find " + typeString + " in customTypeLookup"); } // Record the file, start, end line nums in the CustomType currentType.file = file; currentType.startLineNum = startLineNum; currentType.endLineNum = endLineNum; // Attempt to match all methods of the current type within the text, simularly recording start and end line nums ParseMethodsInFile(currentType, text, typeMatch.Index, currentLineNum); // Reset linenum/index back to the currentType before moving onto next type currentLineNum = currentType.startLineNum; currentIndex = typeMatch.Index; previousType = currentType; typesInFile.Add(currentType); // Debugging to ensure all methods found in text, compared to what is contained in the assembly //Debug.LogError("Class matched: " + classString + ", StartLineNum = " + currentType.startLineNum + ", EndLineNum = " + currentType.endLineNum); //if (numMatchesFound == currentType.methods.Count) { // Debug.LogError("**FOUND ALL METHODS IN " + currentType + ": " + numMatchesFound + " out of " + currentType.methods.Count); //} //else { // Debug.LogError("!!DID NOT FIND ALL METHODS IN " + currentType + ": " + numMatchesFound + " out of " + currentType.methods.Count); //} } // end type match iteration return(typesInFile); }