public void Run () { var assemblies = GetAllAssemblies (); assemblies.ContinueWith (delegate(Task<HashSet<IAssembly>> arg) { using (var monitor = IdeApp.Workbench.ProgressMonitors.GetSearchProgressMonitor (true, true)) { monitor.BeginTask (GettextCatalog.GetString ("Building type graph in solution ..."), 1); var tg = new TypeGraph (arg.Result); var node = tg.GetNode (entity.DeclaringTypeDefinition); monitor.EndTask (); if (node == null) return; Gtk.Application.Invoke (delegate { Stack<IList<TypeGraphNode>> derivedTypes = new Stack<IList<TypeGraphNode>> (); derivedTypes.Push (node.DerivedTypes); HashSet<ITypeDefinition> visitedType = new HashSet<ITypeDefinition> (); while (derivedTypes.Count > 0) { foreach (var derived in derivedTypes.Pop ()) { if (visitedType.Contains (derived.TypeDefinition)) continue; derivedTypes.Push (tg.GetNode (derived.TypeDefinition).DerivedTypes); visitedType.Add (derived.TypeDefinition); var impMember = derived.TypeDefinition.Compilation.Import (entity); if (impMember == null) continue; IMember derivedMember; if (entity.DeclaringTypeDefinition.Kind == TypeKind.Interface) { derivedMember = derived.TypeDefinition.GetMembers (null, GetMemberOptions.IgnoreInheritedMembers).FirstOrDefault ( m => m.ImplementedInterfaceMembers.Any (im => im.Region == entity.Region) ); } else { derivedMember = InheritanceHelper.GetDerivedMember (impMember, derived.TypeDefinition); } if (derivedMember == null || string.IsNullOrEmpty (derivedMember.Region.FileName)) continue; var tf = TextFileProvider.Instance.GetReadOnlyTextEditorData (derivedMember.Region.FileName); var start = tf.LocationToOffset (derivedMember.Region.Begin); tf.SearchRequest.SearchPattern = derivedMember.Name; var sr = tf.SearchForward (start); if (sr != null) start = sr.Offset; monitor.ReportResult (new MemberReference (derivedMember, derivedMember.Region, start, derivedMember.Name.Length)); } } }); } }); }
public void Run () { var assemblies = new HashSet<IAssembly> (); foreach (var project in IdeApp.ProjectOperations.CurrentSelectedSolution.GetAllProjects ()) { var comp = TypeSystemService.GetCompilation (project); if (comp == null) continue; assemblies.Add (comp.MainAssembly); } TypeGraph tg = new TypeGraph (assemblies); var node = tg.GetNode (entity.DeclaringTypeDefinition); using (var monitor = IdeApp.Workbench.ProgressMonitors.GetSearchProgressMonitor (true, true)) { Stack<IList<TypeGraphNode>> derivedTypes = new Stack<IList<TypeGraphNode>> (); derivedTypes.Push (node.DerivedTypes); HashSet<ITypeDefinition> visitedType = new HashSet<ITypeDefinition> (); while (derivedTypes.Count > 0) { foreach (var derived in derivedTypes.Pop ()) { if (visitedType.Contains (derived.TypeDefinition)) continue; derivedTypes.Push (tg.GetNode (derived.TypeDefinition).DerivedTypes); visitedType.Add (derived.TypeDefinition); var impMember = derived.TypeDefinition.Compilation.Import (entity); if (impMember == null) continue; IMember derivedMember; if (entity.DeclaringTypeDefinition.Kind == TypeKind.Interface) { derivedMember = derived.TypeDefinition.GetMembers (null, GetMemberOptions.IgnoreInheritedMembers).FirstOrDefault ( m => m.ImplementedInterfaceMembers.Any (im => im.Region == entity.Region) ); } else { derivedMember = InheritanceHelper.GetDerivedMember (impMember, derived.TypeDefinition); } if (derivedMember == null) continue; var tf = TextFileProvider.Instance.GetReadOnlyTextEditorData (derivedMember.Region.FileName); var start = tf.LocationToOffset (derivedMember.Region.Begin); tf.SearchRequest.SearchPattern = derivedMember.Name; var sr = tf.SearchForward (start); if (sr != null) start = sr.Offset; monitor.ReportResult (new MemberReference (derivedMember, derivedMember.Region, start, derivedMember.Name.Length)); } } } }
IList<AstNode> Rename(string fullyQualifiedName, string newName, bool includeOverloads) { var sym = GetSymbol(compilation, fullyQualifiedName); Assert.NotNull(sym); var graph = new TypeGraph(compilation.Assemblies); var col = new SymbolCollector(); col.IncludeOverloads = includeOverloads; col.GroupForRenaming = true; var scopes = findReferences.GetSearchScopes(col.GetRelatedSymbols(graph, sym)); List<AstNode> result = new List<AstNode>(); findReferences.RenameReferencesInFile( scopes, newName, new CSharpAstResolver(compilation, syntaxTree, unresolvedFile), delegate(RenameCallbackArguments obj) { result.Add (obj.NodeToReplace); }, delegate(Error obj) { }); return result; }
/// <summary> /// Builds a graph of derived type definitions. /// </summary> public static TypeGraphNode BuildDerivedTypesGraph(ITypeDefinition baseType) { if (baseType == null) throw new ArgumentNullException("baseType"); var solutionSnapshot = GetSolutionSnapshot(baseType.Compilation); var assemblies = GetProjectsThatCouldReferenceEntity(baseType).Select(p => solutionSnapshot.GetCompilation(p).MainAssembly); var graph = new TypeGraph(assemblies); var node = graph.GetNode(baseType); if (node != null) { // only derived types were requested, so don't return the base types // (this helps the GC to collect the unused parts of the graph more quickly) node.BaseTypes.Clear(); return node; } else { return new TypeGraphNode(baseType); } }
/// <summary> /// Gets the related symbols. /// </summary> /// <returns>The related symbols.</returns> /// <param name="g">The type graph.</param> /// <param name="m">The symbol to search</param> public IEnumerable<ISymbol> GetRelatedSymbols(TypeGraph g, ISymbol m) { switch (m.SymbolKind) { case SymbolKind.TypeDefinition: return CollectTypeRelatedMembers ((ITypeDefinition)m); case SymbolKind.Field: case SymbolKind.Operator: case SymbolKind.Variable: case SymbolKind.Parameter: case SymbolKind.TypeParameter: return new ISymbol[] { m }; case SymbolKind.Constructor: if (GroupForRenaming) return GetRelatedSymbols (g, ((IMethod)m).DeclaringTypeDefinition); List<ISymbol> constructorSymbols = new List<ISymbol> (); if (IncludeOverloads) { foreach (var m3 in CollectOverloads (g, (IMethod)m)) { constructorSymbols.Add (m3); } } return constructorSymbols; case SymbolKind.Destructor: if (GroupForRenaming) return GetRelatedSymbols (g, ((IMethod)m).DeclaringTypeDefinition); return new ISymbol[] { m }; case SymbolKind.Indexer: case SymbolKind.Event: case SymbolKind.Property: case SymbolKind.Method: { var member = (IMember)m; List<ISymbol> symbols = new List<ISymbol> (); if (member.ImplementedInterfaceMembers.Count > 0) { foreach (var m2 in member.ImplementedInterfaceMembers) { symbols.AddRange (GetRelatedSymbols (g, m2)); } } else { symbols.Add (member); } if (member.DeclaringType.Kind == TypeKind.Interface) { foreach (var derivedType in g.GetNode (member.DeclaringTypeDefinition).DerivedTypes) { var mem = SearchMember (derivedType.TypeDefinition, member); if (mem != null) symbols.Add (mem); } } if (IncludeOverloads) { IncludeOverloads = false; if (member is IMethod) { foreach (var m3 in CollectOverloads (g, (IMethod)member)) { symbols.AddRange (GetRelatedSymbols (g, m3)); } } else if (member.SymbolKind == SymbolKind.Indexer) { symbols.AddRange (member.DeclaringTypeDefinition.GetProperties (p => p.IsIndexer)); } } return MakeUnique (symbols); } case SymbolKind.Namespace: // TODO? return new ISymbol[] { m }; default: throw new ArgumentOutOfRangeException ("symbol:"+m.SymbolKind); } }
static IEnumerable<ISymbol> CollectOverloads(TypeGraph g, IMethod method) { return method.DeclaringType .GetMethods (m => m.Name == method.Name) .Where (m => m != method); }
IEnumerable<ISymbol> GetRelatedSymbols(ISymbol entity) { TypeGraph typeGraph = new TypeGraph(new [] { compilation.MainAssembly }); var symbolCollector = new SymbolCollector(); return symbolCollector.GetRelatedSymbols(typeGraph, entity); }
/// <summary> /// Gets the related symbols. /// </summary> /// <returns>The related symbols.</returns> /// <param name="g">The type graph.</param> /// <param name="m">The symbol to search</param> public IEnumerable <ISymbol> GetRelatedSymbols(TypeGraph g, ISymbol m) { switch (m.SymbolKind) { case SymbolKind.TypeDefinition: return(CollectTypeRelatedMembers((ITypeDefinition)m)); case SymbolKind.Field: case SymbolKind.Operator: case SymbolKind.Variable: case SymbolKind.Parameter: case SymbolKind.TypeParameter: return(new ISymbol[] { m }); case SymbolKind.Constructor: if (GroupForRenaming) { return(GetRelatedSymbols(g, ((IMethod)m).DeclaringTypeDefinition)); } List <ISymbol> constructorSymbols = new List <ISymbol> (); if (IncludeOverloads) { foreach (var m3 in CollectOverloads(g, (IMethod)m)) { constructorSymbols.Add(m3); } } return(constructorSymbols); case SymbolKind.Destructor: if (GroupForRenaming) { return(GetRelatedSymbols(g, ((IMethod)m).DeclaringTypeDefinition)); } return(new ISymbol[] { m }); case SymbolKind.Indexer: case SymbolKind.Event: case SymbolKind.Property: case SymbolKind.Method: { var member = (IMember)m; List <ISymbol> symbols = new List <ISymbol> (); if (member.ImplementedInterfaceMembers.Count > 0) { foreach (var m2 in member.ImplementedInterfaceMembers) { symbols.AddRange(GetRelatedSymbols(g, m2)); } } else { symbols.Add(member); } if (member.DeclaringType.Kind == TypeKind.Interface) { foreach (var derivedType in g.GetNode(member.DeclaringTypeDefinition).DerivedTypes) { var mem = SearchMember(derivedType.TypeDefinition, member); if (mem != null) { symbols.Add(mem); } } } if (IncludeOverloads) { IncludeOverloads = false; if (member is IMethod) { foreach (var m3 in CollectOverloads(g, (IMethod)member)) { symbols.AddRange(GetRelatedSymbols(g, m3)); } } else if (member.SymbolKind == SymbolKind.Indexer) { symbols.AddRange(member.DeclaringTypeDefinition.GetProperties(p => p.IsIndexer)); } } return(MakeUnique(symbols)); } case SymbolKind.Namespace: // TODO? return(new ISymbol[] { m }); default: throw new ArgumentOutOfRangeException("symbol:" + m.SymbolKind); } }
static IEnumerable <ISymbol> CollectOverloads(TypeGraph g, IMethod method) { return(method.DeclaringType .GetMethods(m => m.Name == method.Name) .Where(m => m != method)); }