protected override void Run (object data) { Document doc = IdeApp.Workbench.ActiveDocument; if (doc == null || doc.FileName == FilePath.Null || IdeApp.ProjectOperations.CurrentSelectedSolution == null) return; ITextBuffer editor = doc.GetContent<ITextBuffer> (); if (editor == null) return; int line, column; editor.GetLineColumnFromPosition (editor.CursorPosition, out line, out column); ProjectDom ctx = doc.Dom; ResolveResult resolveResult; INode item; CurrentRefactoryOperationsHandler.GetItem (ctx, doc, editor, out resolveResult, out item); IMember eitem = resolveResult != null ? (resolveResult.CallingMember ?? resolveResult.CallingType) : null; string itemName = null; if (item is IMember) itemName = ((IMember)item).Name; if (item != null && eitem != null && (eitem.Equals (item) || (eitem.Name == itemName && !(eitem is IProperty) && !(eitem is IMethod)))) { item = eitem; eitem = null; } IType eclass = null; if (item is IType) { if (((IType)item).ClassType == ClassType.Interface) eclass = CurrentRefactoryOperationsHandler.FindEnclosingClass (ctx, editor.Name, line, column); else eclass = (IType)item; if (eitem is IMethod && ((IMethod)eitem).IsConstructor && eitem.DeclaringType.Equals (item)) { item = eitem; eitem = null; } } Refactorer refactorer = new Refactorer (ctx, doc.CompilationUnit, eclass, item, null); refactorer.FindDerivedClasses (); }
protected override void Update (CommandArrayInfo ainfo) { Document doc = IdeApp.Workbench.ActiveDocument; if (doc == null || doc.FileName == FilePath.Null || IdeApp.ProjectOperations.CurrentSelectedSolution == null) return; ITextBuffer editor = doc.GetContent<ITextBuffer> (); if (editor == null) return; bool added = false; int line, column; editor.GetLineColumnFromPosition (editor.CursorPosition, out line, out column); ProjectDom ctx = doc.Dom; ResolveResult resolveResult; INode item; GetItem (ctx, doc, editor, out resolveResult, out item); IMember eitem = resolveResult != null ? (resolveResult.CallingMember ?? resolveResult.CallingType) : null; string itemName = null; if (item is IMember) itemName = ((IMember)item).Name; if (item != null && eitem != null && (eitem.Equals (item) || (eitem.Name == itemName && !(eitem is IProperty) && !(eitem is IMethod)))) { // If this occurs, then @item is either its own enclosing item, in // which case, we don't want to show it twice, or it is the base-class // version of @eitem, in which case we don't want to show the base-class // @item, we'd rather show the item the user /actually/ requested, @eitem. item = eitem; eitem = null; } IType eclass = null; if (item is IType) { if (((IType)item).ClassType == ClassType.Interface) eclass = FindEnclosingClass (ctx, editor.Name, line, column); else eclass = (IType)item; if (eitem is IMethod && ((IMethod)eitem).IsConstructor && eitem.DeclaringType.Equals (item)) { item = eitem; eitem = null; } } INode realItem = item; if (item is InstantiatedType) realItem = ((InstantiatedType)item).UninstantiatedType; if (realItem is CompoundType) { editor.GetLineColumnFromPosition (editor.CursorPosition, out line, out column); ((CompoundType)realItem).SetMainPart (doc.FileName, line, column); item = realItem; } RefactoringOptions options = new RefactoringOptions () { Document = doc, Dom = ctx, ResolveResult = resolveResult, SelectedItem = realItem }; if (resolveResult != null && resolveResult.ResolvedExpression != null && !string.IsNullOrEmpty (resolveResult.ResolvedExpression.Expression)) { bool resolveDirect; List<string> namespaces = QuickFixHandler.GetResolveableNamespaces (options, out resolveDirect); if (item == null || namespaces.Count > 1) { CommandInfoSet resolveMenu = new CommandInfoSet (); resolveMenu.Text = GettextCatalog.GetString ("Resolve"); if (item == null) { foreach (string ns in namespaces) { // remove used namespaces for conflict resolving. if (options.Document.CompilationUnit.IsNamespaceUsedAt (ns, options.ResolveResult.ResolvedExpression.Region.Start)) continue; CommandInfo info = resolveMenu.CommandInfos.Add ("using " + ns + ";", new RefactoryOperation (new ResolveNameOperation (ctx, doc, resolveResult, ns).AddImport)); info.Icon = MonoDevelop.Ide.Gui.Stock.AddNamespace; } if (!(resolveResult is UnresolvedMemberResolveResult)) resolveMenu.CommandInfos.AddSeparator (); } else { // remove all unused namespaces (for resolving conflicts) namespaces.RemoveAll (ns => !doc.CompilationUnit.IsNamespaceUsedAt (ns, resolveResult.ResolvedExpression.Region.Start)); } if (resolveDirect) { foreach (string ns in namespaces) { resolveMenu.CommandInfos.Add (ns, new RefactoryOperation (new ResolveNameOperation (ctx, doc, resolveResult, ns).ResolveName)); } } if (namespaces.Count > (item == null ? 0 : 1)) ainfo.Add (resolveMenu, null); } } var unit = doc.CompilationUnit; if (unit != null && unit.Usings != null && unit.Usings.Any (u => !u.IsFromNamespace && u.Region.Contains (line, column))) { CommandInfoSet organizeUsingsMenu = new CommandInfoSet (); organizeUsingsMenu.Text = GettextCatalog.GetString ("_Organize Usings"); organizeUsingsMenu.CommandInfos.Add (IdeApp.CommandService.GetCommandInfo (RefactoryCommands.RemoveUnusedImports), new RefactoryOperation (delegate { new RemoveUnusedImportsHandler ().Start (options); })); organizeUsingsMenu.CommandInfos.Add (IdeApp.CommandService.GetCommandInfo (MonoDevelop.Refactoring.RefactoryCommands.SortImports), new RefactoryOperation (delegate { new SortImportsHandler ().Start (options); })); organizeUsingsMenu.CommandInfos.Add (IdeApp.CommandService.GetCommandInfo (MonoDevelop.Refactoring.RefactoryCommands.RemoveSortImports), new RefactoryOperation (delegate { new RemoveSortImportsHandler ().Start (options); })); ainfo.Add (organizeUsingsMenu, null); added = true; } CommandInfoSet ciset = new CommandInfoSet (); ciset.Text = GettextCatalog.GetString ("Refactor"); foreach (var refactoring in RefactoringService.Refactorings) { if (refactoring.IsValid (options)) { CommandInfo info = new CommandInfo (refactoring.GetMenuDescription (options)); info.AccelKey = refactoring.AccelKey; ciset.CommandInfos.Add (info, new RefactoryOperation (new RefactoringOperationWrapper (refactoring, options).Operation)); } } if (ciset.CommandInfos.Count > 0) { ainfo.Add (ciset, null); added = true; } ICompilationUnit pinfo = doc.CompilationUnit; if (pinfo == null) return; Refactorer refactorer = new Refactorer (ctx, pinfo, eclass, realItem, null); if (IdeApp.ProjectOperations.CanJumpToDeclaration (item)) { if (item is CompoundType) { CommandInfoSet declSet = new CommandInfoSet (); declSet.Text = GettextCatalog.GetString ("_Go to declaration"); CompoundType ct = (CompoundType)item; foreach (IType part in ct.Parts) { Refactorer partRefactorer = new Refactorer (ctx, pinfo, eclass, part, null); declSet.CommandInfos.Add (string.Format (GettextCatalog.GetString ("{0}, Line {1}"), FormatFileName (part.CompilationUnit.FileName), part.Location.Line), new RefactoryOperation (partRefactorer.GoToDeclaration)); } ainfo.Add (declSet); } else { ainfo.Add (IdeApp.CommandService.GetCommandInfo (RefactoryCommands.GotoDeclaration), new RefactoryOperation (refactorer.GoToDeclaration)); } added = true; } if ((item is IMember || item is LocalVariable || item is IParameter) && !(item is IType)) ainfo.Add (IdeApp.CommandService.GetCommandInfo (RefactoryCommands.FindReferences), new RefactoryOperation (refactorer.FindReferences)); Ambience ambience = AmbienceService.GetAmbienceForFile (pinfo.FileName); bool includeModifyCommands = this.IsModifiable (item); bool canRename; if ((item is LocalVariable) || (item is IParameter)) { canRename = true; } else if (item is IType) { canRename = ((IType)item).SourceProject != null; } else if (item is IMember) { IType cls = ((IMember)item).DeclaringType; canRename = cls != null && cls.SourceProject != null; } else { canRename = false; } // case: clicked on base in "constructor" - so pointing to the base constructor using argument count // not 100% correct, but it's the fastest thing to do. if (resolveResult is BaseResolveResult && eitem is IMethod && ((IMethod)eitem).IsConstructor) { IType type = item as IType; IMethod baseConstructor = null; int idx1 = resolveResult.ResolvedExpression.Expression.IndexOf ('('); int idx2 = resolveResult.ResolvedExpression.Expression.IndexOf (')'); int paramCount = 0; if (idx1 > 0 && idx2 > 0) { if (idx2 - idx1 > 1) paramCount++; for (int i=idx1; i < idx2; i++) { if (resolveResult.ResolvedExpression.Expression[i] == ',') paramCount++; } } foreach (IMethod m in type.Methods) { if (m.IsConstructor && m.Parameters.Count == paramCount) baseConstructor = m; } Refactorer refactorer2 = new Refactorer (ctx, pinfo, baseConstructor.DeclaringType, baseConstructor, null); ainfo.Add (GettextCatalog.GetString ("Go to _base"), new RefactoryOperation (refactorer2.GoToBase)); } if (item is IType) { IType cls = (IType) item; if (cls.BaseType != null && cls.ClassType == ClassType.Class) { foreach (IReturnType rt in cls.BaseTypes) { IType bc = ctx.GetType (rt); if (bc != null && bc.ClassType != ClassType.Interface/* TODO: && IdeApp.ProjectOperations.CanJumpToDeclaration (bc)*/) { ainfo.Add (GettextCatalog.GetString ("Go to _base"), new RefactoryOperation (refactorer.GoToBase)); break; } } } if ((cls.ClassType == ClassType.Class && !cls.IsSealed) || cls.ClassType == ClassType.Interface) { ainfo.Add (cls.ClassType != ClassType.Interface ? GettextCatalog.GetString ("Find _derived classes") : GettextCatalog.GetString ("Find _implementor classes"), new RefactoryOperation (refactorer.FindDerivedClasses)); } if (cls.SourceProject != null && includeModifyCommands && ((cls.ClassType == ClassType.Class) || (cls.ClassType == ClassType.Struct))) { ciset.CommandInfos.Add (GettextCatalog.GetString ("_Encapsulate Fields..."), new RefactoryOperation (refactorer.EncapsulateField)); ciset.CommandInfos.Add (GettextCatalog.GetString ("Override/Implement members..."), new RefactoryOperation (refactorer.OverrideOrImplementMembers)); } ainfo.Add (IdeApp.CommandService.GetCommandInfo (RefactoryCommands.FindReferences), new RefactoryOperation (refactorer.FindReferences)); // if (canRename) // ciset.CommandInfos.Add (GettextCatalog.GetString ("_Rename"), new RefactoryOperation (refactorer.Rename)); if (canRename && cls.ClassType == ClassType.Interface && eclass != null) { // is now provided by the refactoring command infrastructure: // ciset.CommandInfos.Add (GettextCatalog.GetString ("Implement Interface (explicit)"), new RefactoryOperation (refactorer.ImplementExplicitInterface)); // ciset.CommandInfos.Add (GettextCatalog.GetString ("Implement Interface (implicit)"), new RefactoryOperation (refactorer.ImplementImplicitInterface)); } else if (canRename && includeModifyCommands && cls.BaseType != null && cls.ClassType != ClassType.Interface && cls == eclass) { // Class might have interfaces... offer to implement them CommandInfoSet impset = new CommandInfoSet (); CommandInfoSet expset = new CommandInfoSet (); CommandInfoSet abstactset = new CommandInfoSet (); bool ifaceAdded = false; bool abstractAdded = false; foreach (IReturnType rt in cls.BaseTypes) { IType iface = ctx.GetType (rt); if (iface == null) continue; if (iface.ClassType == ClassType.Interface) { Refactorer ifaceRefactorer = new Refactorer (ctx, pinfo, cls, iface, rt); impset.CommandInfos.Add (ambience.GetString (rt, OutputFlags.IncludeGenerics), new RefactoryOperation (ifaceRefactorer.ImplementImplicitInterface)); expset.CommandInfos.Add (ambience.GetString (rt, OutputFlags.IncludeGenerics), new RefactoryOperation (ifaceRefactorer.ImplementExplicitInterface)); ifaceAdded = true; } else if (ContainsAbstractMembers (iface)) { Refactorer ifaceRefactorer = new Refactorer (ctx, pinfo, cls, iface, rt); abstactset.CommandInfos.Add (ambience.GetString (rt, OutputFlags.IncludeGenerics), new RefactoryOperation (ifaceRefactorer.ImplementAbstractMembers)); abstractAdded = true; } } if (ifaceAdded) { impset.Text = GettextCatalog.GetString ("Implement Interface (implicit)"); ciset.CommandInfos.Add (impset, null); expset.Text = GettextCatalog.GetString ("Implement Interface (explicit)"); ciset.CommandInfos.Add (expset, null); } if (abstractAdded) { abstactset.Text = GettextCatalog.GetString ("Implement abstract members"); ciset.CommandInfos.Add (abstactset, null); } } } else if (item is IField) { if (includeModifyCommands) { if (canRename) ciset.CommandInfos.Add (GettextCatalog.GetString ("_Encapsulate Field..."), new RefactoryOperation (refactorer.EncapsulateField)); } } else if (item is IMethod) { IMethod method = item as IMethod; if (method.IsOverride) { ainfo.Add (GettextCatalog.GetString ("Go to _base"), new RefactoryOperation (refactorer.GoToBase)); added = true; } } if (added) ainfo.AddSeparator (); /* while (item != null) { CommandInfo ci; // case: clicked on base in "constructor" - so pointing to the base constructor using argument count // not 100% correct, but it's the fastest thing to do. if (resolveResult is BaseResolveResult && eitem is IMethod && ((IMethod)eitem).IsConstructor) { IType type = item as IType; IMethod baseConstructor = null; int idx1 = resolveResult.ResolvedExpression.Expression.IndexOf ('('); int idx2 = resolveResult.ResolvedExpression.Expression.IndexOf (')'); int paramCount = 0; if (idx1 > 0 && idx2 > 0) { if (idx2 - idx1 > 1) paramCount++; for (int i=idx1; i < idx2; i++) { if (resolveResult.ResolvedExpression.Expression[i] == ',') paramCount++; } } foreach (IMethod m in type.Methods) { if (m.IsConstructor && m.Parameters.Count == paramCount) baseConstructor = m; } if (baseConstructor != null && (ci = BuildRefactoryMenuForItem (ctx, doc.CompilationUnit, null, baseConstructor, true)) != null) { ainfo.Add (ci, null); added = true; } } // Add the selected item if ((ci = BuildRefactoryMenuForItem (ctx, doc.CompilationUnit, eclass, item, IsModifiable (item))) != null) { ainfo.Add (ci, null); added = true; } if (item is IParameter) { // Add the encompasing method for the previous item in the menu item = ((IParameter) item).DeclaringMember; if (item != null && (ci = BuildRefactoryMenuForItem (ctx, doc.CompilationUnit, null, item, true)) != null) { ainfo.Add (ci, null); added = true; } } if (item is IMember && !(eitem != null && eitem is IMember)) { // Add the encompasing class for the previous item in the menu item = ((IMember) item).DeclaringType; if (item != null && (ci = BuildRefactoryMenuForItem (ctx, doc.CompilationUnit, null, item, IsModifiable (item))) != null) { ainfo.Add (ci, null); added = true; } } item = eitem; eitem = null; eclass = null; } if (added) ainfo.AddSeparator ();*/ }
public void FindReferences () { IMember member = widget.ActiveMember; if (member == null) return; ProjectDom dom = ProjectDomService.GetProjectDom (IdeApp.ProjectOperations.CurrentSelectedProject); if (dom == null) return; Refactorer refactorer = new Refactorer (dom, null, null, member, null); refactorer.FindReferences (); }