/// <summary> /// The list of paths from this method to the given called target method. /// </summary> public List <List <ModelMethod> > PathsTo(ModelMethod targetMethod) { List <List <ModelMethod> > paths = new List <List <ModelMethod> >(); paths.Add(new List <ModelMethod>() { this }); return(BuildPathsTo(paths, targetMethod)); }
private void BuildAllCalledByMethods(HashSet <ModelMethod> calls, ModelMethod parent) { foreach (ModelMethod m in parent.CalledByMethods) { if (!calls.Contains(m)) { calls.Add(m); this.BuildAllCalledByMethods(calls, m); } } }
/// <summary> /// Compares whether two ModelMethod objects reference the same CLR method. /// </summary> public override bool Equals(object obj) { ModelMethod other = obj as ModelMethod; if (Object.ReferenceEquals(other, null)) { return(false); } else { return(this.MethodBase.Equals(other.MethodBase)); } }
/// <summary> /// Returns the interface methods this method implements. /// </summary> public IEnumerable <MethodInfo> GetImplementedInterfaceMethods(ModelMethod byMethod) { if ((this.interfaceMapping == null) && (byMethod.DeclaringType.IsInterface == false)) { lock (this) { if (this.interfaceMapping == null) { this.interfaceMapping = new Dictionary <MethodBase, List <MethodInfo> >(); foreach (Type itype in this.runtimeType.GetInterfaces()) { InterfaceMapping map = this.runtimeType.GetInterfaceMap(itype); for (int i = 0; i < map.InterfaceMethods.Length; i++) { List <MethodInfo> list; if (!this.interfaceMapping.TryGetValue(map.TargetMethods[i], out list)) { list = this.interfaceMapping[map.TargetMethods[i]] = new List <MethodInfo>(); } list.Add(map.InterfaceMethods[i]); } } } } } List <MethodInfo> result; if (byMethod.DeclaringType.IsInterface) { return(EmptyMethodInfoSet); } else if (this.interfaceMapping.TryGetValue(byMethod.MethodBase, out result)) { return(result); } else { return(EmptyMethodInfoSet); } }
/// <summary> /// Process the given session and return a codemodel containing /// the in-memory method call network. /// </summary> public CodeModel Process(StaticCodeAnalyzerSession session) { List <ModelAssembly> massemblies = new List <ModelAssembly>(); List <ModelType> mtypes = new List <ModelType>(); Dictionary <string, ModelMethod> mmethods = new Dictionary <string, ModelMethod>(); ILanguageInfo languageInfo = session.LanguageInfo; IAnalyzerFilter analyzerFilter = session.AnalyzerFilter; // Retrieve all methods and constructors: foreach (Assembly asm in session.Assemblies) { try { if ((analyzerFilter != null) && (!analyzerFilter.ProcessAssembly(asm))) { continue; } ModelAssembly masm = new ModelAssembly(asm, languageInfo); massemblies.Add(masm); foreach (Type type in asm.GetTypes()) { try { if ((analyzerFilter != null) && (!analyzerFilter.ProcessType(type))) { continue; } ModelType mtype = new ModelType(masm, type, languageInfo); mtypes.Add(mtype); foreach (MethodBase mb in type.GetConstructors(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)) { if ((analyzerFilter != null) && (!analyzerFilter.ProcessMethod(mb))) { continue; } mmethods[GetMethodKey(mb)] = new ModelMethod(mtype, mb, languageInfo); } foreach (MethodBase mb in type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly)) { if ((analyzerFilter != null) && (!analyzerFilter.ProcessMethod(mb))) { continue; } mmethods[GetMethodKey(mb)] = new ModelMethod(mtype, mb, languageInfo); } } catch (Exception ex) { // Rethrow with mode info: throw new TargetInvocationException( String.Format("Error reading type {0}: {1} (See innerException.)", type.FullName, ex.Message), ex ); } } } catch (ReflectionTypeLoadException ex) { // Rethrow with mode info: throw new TargetInvocationException( String.Format("Error reading assembly {0}: {1} (See innerException.)", asm.FullName, ex.Message), ex.LoaderExceptions.FirstOrDefault() ?? ex ); } catch (Exception ex) { // Rethrow with mode info: throw new TargetInvocationException( String.Format("Error reading assembly {0}: {1} (See innerException.)", asm.FullName, ex.Message), ex ); } } // Build network of method calls: foreach (ModelMethod m in mmethods.Values) { try { MethodBodyReader reader = new MethodBodyReader(m.MethodBase); foreach (MethodBase calledmb in reader.GetCalledMethods(true, true)) { ModelMethod calledm = FindMethod(mmethods, calledmb); if (calledm != null) { m.CallsMethods.Add(calledm); } } } catch (InvalidOperationException ex) { Debug.WriteLine(ex.Message); } } // Construct a code model: CodeModel codeModel = new CodeModel( massemblies, mtypes, mmethods.Values); // Apply processors: foreach (IProcessor processor in session.Processors) { processor.Process(codeModel); } // Construct & return a code model: return(codeModel); }
private List <List <ModelMethod> > BuildPathsTo(List <List <ModelMethod> > paths, ModelMethod targetMethod) { List <List <ModelMethod> > newPaths = new List <List <ModelMethod> >(); foreach (var path in paths) { if (path.Last().Equals(targetMethod)) { newPaths.Add(path); } else { foreach (var callsMethod in path.Last().CallsMethods) { // Skip recursive calls: if (path.Contains(callsMethod)) { continue; } if (callsMethod.Equals(targetMethod)) { List <ModelMethod> newPath = new List <ModelMethod>(path); newPath.Add(callsMethod); newPaths.Add(newPath); } else if (callsMethod.GetAllCallsMethods().Contains(targetMethod)) { List <ModelMethod> newPath = new List <ModelMethod>(path); newPath.Add(callsMethod); newPaths.AddRange(BuildPathsTo(new List <List <ModelMethod> >() { newPath }, targetMethod)); } } } } return(newPaths); }