diff --git a/Nodejs/Product/Nodejs/EditFilter.cs b/Nodejs/Product/Nodejs/EditFilter.cs index 7509928c6..88871daa8 100644 --- a/Nodejs/Product/Nodejs/EditFilter.cs +++ b/Nodejs/Product/Nodejs/EditFilter.cs @@ -136,8 +136,6 @@ _intellisenseStack.TopSession is ICompletionSession && } } else if (pguidCmdGroup == VSConstants.GUID_VSStandardCommandSet97) { switch ((VSConstants.VSStd97CmdID)nCmdID) { - case VSConstants.VSStd97CmdID.GotoDefn: return GotoDefinition(); - case VSConstants.VSStd97CmdID.FindReferences: return FindAllReferences(); case VSConstants.VSStd97CmdID.Paste: return Paste(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut, out hr); } @@ -165,491 +163,6 @@ private int Paste(ref Guid pguidCmdGroup, uint nCmdID, uint nCmdexecopt, IntPtr return hr; } - /// - /// Implements Goto Definition. Called when the user selects Goto Definition from the - /// context menu or hits the hotkey associated with Goto Definition. - /// - /// If there is 1 and only one definition immediately navigates to it. If there are - /// no references displays a dialog box to the user. Otherwise it opens the find - /// symbols dialog with the list of results. - /// - private int GotoDefinition() { - UpdateStatusForIncompleteAnalysis(); - - var analysis = AnalyzeExpression(); - - Dictionary references, definitions, values; - GetDefsRefsAndValues(analysis, out definitions, out references, out values); - - if ((values.Count + definitions.Count) == 1) { - if (values.Count != 0) { - foreach (var location in values.Keys) { - GotoLocation(location); - break; - } - } else { - foreach (var location in definitions.Keys) { - GotoLocation(location); - break; - } - } - } else if (values.Count + definitions.Count == 0) { - if (String.IsNullOrWhiteSpace(analysis.Expression)) { - MessageBox.Show(String.Format("Cannot go to definition. The cursor is not on a symbol."), SR.ProductName); - } else { - MessageBox.Show(String.Format("Cannot go to definition \"{0}\"", analysis.Expression), SR.ProductName); - } - } else if (definitions.Count == 0) { - ShowFindSymbolsDialog(analysis, new SymbolList("Values", StandardGlyphGroup.GlyphForwardType, values.Values)); - } else if (values.Count == 0) { - ShowFindSymbolsDialog(analysis, new SymbolList("Definitions", StandardGlyphGroup.GlyphLibrary, definitions.Values)); - } else { - ShowFindSymbolsDialog(analysis, - new LocationCategory("Goto Definition", - new SymbolList("Definitions", StandardGlyphGroup.GlyphLibrary, definitions.Values), - new SymbolList("Values", StandardGlyphGroup.GlyphForwardType, values.Values) - ) - ); - } - - return VSConstants.S_OK; - } - - private ExpressionAnalysis AnalyzeExpression() { - return VsProjectAnalyzer.AnalyzeExpression( - _textView.TextBuffer.CurrentSnapshot, - _textView.GetCaretSpan(), - false - ); - } - - /// - /// Moves the caret to the specified location, staying in the current text view - /// if possible. - /// - /// https://pytools.codeplex.com/workitem/1649 - /// - private void GotoLocation(LocationInfo location) { - Debug.Assert(location != null); - Debug.Assert(location.Line > 0); - Debug.Assert(location.Column > 0); - - if (CommonUtils.IsSamePath(location.FilePath, _textView.GetFilePath())) { - var adapterFactory = _serviceProvider.GetComponentModel().GetService(); - var viewAdapter = adapterFactory.GetViewAdapter(_textView); - viewAdapter.SetCaretPos(location.Line - 1, location.Column - 1); - viewAdapter.CenterLines(location.Line - 1, 1); - } else { - location.GotoSource(); - } - } - - /// - /// Implements Find All References. Called when the user selects Find All References from - /// the context menu or hits the hotkey associated with find all references. - /// - /// Always opens the Find Symbol Results box to display the results. - /// - private int FindAllReferences() { - UpdateStatusForIncompleteAnalysis(); - - var analysis = AnalyzeExpression(); - - var locations = GetFindRefLocations(analysis); - - ShowFindSymbolsDialog(analysis, locations); - - return VSConstants.S_OK; - } - - internal static LocationCategory GetFindRefLocations(ExpressionAnalysis analysis) { - Dictionary references, definitions, values; - GetDefsRefsAndValues(analysis, out definitions, out references, out values); - - var locations = new LocationCategory("Find All References", - new SymbolList("Definitions", StandardGlyphGroup.GlyphLibrary, definitions.Values), - new SymbolList("Values", StandardGlyphGroup.GlyphForwardType, values.Values), - new SymbolList("References", StandardGlyphGroup.GlyphReference, references.Values) - ); - return locations; - } - - private static void GetDefsRefsAndValues(ExpressionAnalysis provider, out Dictionary definitions, out Dictionary references, out Dictionary values) { - references = new Dictionary(); - definitions = new Dictionary(); - values = new Dictionary(); - - foreach (var v in provider.Variables) { - if (v.Location.FilePath == null) { - // ignore references in the REPL - continue; - } - - switch (v.Type) { - case VariableType.Definition: - values.Remove(v.Location); - definitions[v.Location] = new SimpleLocationInfo(provider.Expression, v.Location, StandardGlyphGroup.GlyphGroupField); - break; - case VariableType.Reference: - references[v.Location] = new SimpleLocationInfo(provider.Expression, v.Location, StandardGlyphGroup.GlyphGroupField); - break; - case VariableType.Value: - if (!definitions.ContainsKey(v.Location)) { - values[v.Location] = new SimpleLocationInfo(provider.Expression, v.Location, StandardGlyphGroup.GlyphGroupField); - } - break; - } - } - } - - /// - /// Opens the find symbols dialog with a list of results. This is done by requesting - /// that VS does a search against our library GUID. Our library then responds to - /// that request by extracting the prvoided symbol list out and using that for the - /// search results. - /// - private static void ShowFindSymbolsDialog(ExpressionAnalysis provider, IVsNavInfo symbols) { - // ensure our library is loaded so find all references will go to our library - //Package.GetGlobalService(typeof(IPythonLibraryManager)); - - if (provider.Expression != String.Empty) { - var findSym = (IVsFindSymbol)NodejsPackage.GetGlobalService(typeof(SVsObjectSearch)); - VSOBSEARCHCRITERIA2 searchCriteria = new VSOBSEARCHCRITERIA2(); - searchCriteria.eSrchType = VSOBSEARCHTYPE.SO_ENTIREWORD; - searchCriteria.pIVsNavInfo = symbols; - searchCriteria.grfOptions = (uint)_VSOBSEARCHOPTIONS2.VSOBSO_LISTREFERENCES; - searchCriteria.szName = provider.Expression; - - Guid guid = Guid.Empty; - // new Guid("{a5a527ea-cf0a-4abf-b501-eafe6b3ba5c6}") - ErrorHandler.ThrowOnFailure(findSym.DoSearch(new Guid(CommonConstants.LibraryGuid), new VSOBSEARCHCRITERIA2[] { searchCriteria })); - } else { - var statusBar = (IVsStatusbar)CommonPackage.GetGlobalService(typeof(SVsStatusbar)); - statusBar.SetText("The caret must be on valid expression to find all references."); - } - } - - - - internal class LocationCategory : SimpleObjectList, IVsNavInfo, ICustomSearchListProvider { - internal LocationCategory(string name, params SymbolList[] locations) { - foreach (var location in locations) { - if (location.Children.Count > 0) { - Children.Add(location); - } - } - } - - public override uint CategoryField(LIB_CATEGORY lIB_CATEGORY) { - return (uint)(_LIB_LISTTYPE.LLT_HIERARCHY | _LIB_LISTTYPE.LLT_MEMBERS | _LIB_LISTTYPE.LLT_PACKAGE); - } - - #region IVsNavInfo Members - - public int EnumCanonicalNodes(out IVsEnumNavInfoNodes ppEnum) { - ppEnum = new NodeEnumerator(Children); - return VSConstants.S_OK; - } - - public int EnumPresentationNodes(uint dwFlags, out IVsEnumNavInfoNodes ppEnum) { - ppEnum = new NodeEnumerator(Children); - return VSConstants.S_OK; - } - - public int GetLibGuid(out Guid pGuid) { - pGuid = Guid.Empty; - return VSConstants.S_OK; - } - - public int GetSymbolType(out uint pdwType) { - pdwType = (uint)_LIB_LISTTYPE2.LLT_MEMBERHIERARCHY; - return VSConstants.S_OK; - } - - #endregion - - #region ICustomSearchListProvider Members - - public IVsSimpleObjectList2 GetSearchList() { - return this; - } - - #endregion - } - - internal class SimpleLocationInfo : SimpleObject, IVsNavInfoNode { - private readonly LocationInfo _locationInfo; - private readonly StandardGlyphGroup _glyphType; - private readonly string _pathText, _lineText; - - public SimpleLocationInfo(string searchText, LocationInfo locInfo, StandardGlyphGroup glyphType) { - _locationInfo = locInfo; - _glyphType = glyphType; - _pathText = GetSearchDisplayText(); - _lineText = _locationInfo.ProjectEntry.GetLine(_locationInfo.Line); - } - - public override string Name { - get { - return _locationInfo.FilePath; - } - } - - public override string GetTextRepresentation(VSTREETEXTOPTIONS options) { - if (options == VSTREETEXTOPTIONS.TTO_DEFAULT) { - return _pathText + _lineText.Trim(); - } - return String.Empty; - } - - private string GetSearchDisplayText() { - return String.Format("{0} - ({1}, {2}): ", - _locationInfo.FilePath, - _locationInfo.Line, - _locationInfo.Column); - } - - public override string UniqueName { - get { - return _locationInfo.FilePath; - } - } - - public override bool CanGoToSource { - get { - return true; - } - } - - public override VSTREEDISPLAYDATA DisplayData { - get { - var res = new VSTREEDISPLAYDATA(); - res.Image = res.SelectedImage = (ushort)_glyphType; - res.State = (uint)_VSTREEDISPLAYSTATE.TDS_FORCESELECT; - - // This code highlights the text but it gets the wrong region. This should be re-enabled - // and highlight the correct region. - - //res.ForceSelectStart = (ushort)(_pathText.Length + _locationInfo.Column - 1); - //res.ForceSelectLength = (ushort)_locationInfo.Length; - return res; - } - } - - public override void GotoSource(VSOBJGOTOSRCTYPE SrcType) { - _locationInfo.GotoSource(); - } - - #region IVsNavInfoNode Members - - public int get_Name(out string pbstrName) { - pbstrName = _locationInfo.FilePath; - return VSConstants.S_OK; - } - - public int get_Type(out uint pllt) { - pllt = 16; // (uint)_LIB_LISTTYPE2.LLT_MEMBERHIERARCHY; - return VSConstants.S_OK; - } - - #endregion - } - - internal class SymbolList : SimpleObjectList, IVsNavInfo, IVsNavInfoNode, ICustomSearchListProvider, ISimpleObject { - private readonly string _name; - private readonly StandardGlyphGroup _glyphGroup; - - internal SymbolList(string description, StandardGlyphGroup glyphGroup, IEnumerable locations) { - _name = description; - _glyphGroup = glyphGroup; - Children.AddRange(locations); - } - - public override uint CategoryField(LIB_CATEGORY lIB_CATEGORY) { - return (uint)(_LIB_LISTTYPE.LLT_MEMBERS | _LIB_LISTTYPE.LLT_PACKAGE); - } - - #region ISimpleObject Members - - public bool CanDelete { - get { return false; } - } - - public bool CanGoToSource { - get { return false; } - } - - public bool CanRename { - get { return false; } - } - - public string Name { - get { return _name; } - } - - public string UniqueName { - get { return _name; } - } - - public string FullName { - get { - return _name; - } - } - - public string GetTextRepresentation(VSTREETEXTOPTIONS options) { - switch (options) { - case VSTREETEXTOPTIONS.TTO_DISPLAYTEXT: - return _name; - } - return null; - } - - public string TooltipText { - get { return null; } - } - - public object BrowseObject { - get { return null; } - } - - public System.ComponentModel.Design.CommandID ContextMenuID { - get { return null; } - } - - public VSTREEDISPLAYDATA DisplayData { - get { - var res = new VSTREEDISPLAYDATA(); - res.Image = res.SelectedImage = (ushort)_glyphGroup; - return res; - } - } - - public void Delete() { - } - - public void DoDragDrop(OleDataObject dataObject, uint grfKeyState, uint pdwEffect) { - } - - public void Rename(string pszNewName, uint grfFlags) { - } - - public void GotoSource(VSOBJGOTOSRCTYPE SrcType) { - } - - public void SourceItems(out IVsHierarchy ppHier, out uint pItemid, out uint pcItems) { - ppHier = null; - pItemid = 0; - pcItems = 0; - } - - public uint EnumClipboardFormats(_VSOBJCFFLAGS _VSOBJCFFLAGS, VSOBJCLIPFORMAT[] rgcfFormats) { - return VSConstants.S_OK; - } - - public void FillDescription(_VSOBJDESCOPTIONS _VSOBJDESCOPTIONS, IVsObjectBrowserDescription3 pobDesc) { - } - - public IVsSimpleObjectList2 FilterView(uint ListType) { - return this; - } - - #endregion - - #region IVsNavInfo Members - - public int EnumCanonicalNodes(out IVsEnumNavInfoNodes ppEnum) { - ppEnum = new NodeEnumerator(Children); - return VSConstants.S_OK; - } - - public int EnumPresentationNodes(uint dwFlags, out IVsEnumNavInfoNodes ppEnum) { - ppEnum = new NodeEnumerator(Children); - return VSConstants.S_OK; - } - - public int GetLibGuid(out Guid pGuid) { - pGuid = Guid.Empty; - return VSConstants.S_OK; - } - - public int GetSymbolType(out uint pdwType) { - pdwType = (uint)_LIB_LISTTYPE2.LLT_MEMBERHIERARCHY; - return VSConstants.S_OK; - } - - #endregion - - #region ICustomSearchListProvider Members - - public IVsSimpleObjectList2 GetSearchList() { - return this; - } - - #endregion - - #region IVsNavInfoNode Members - - public int get_Name(out string pbstrName) { - pbstrName = "name"; - return VSConstants.S_OK; - } - - public int get_Type(out uint pllt) { - pllt = 16; // (uint)_LIB_LISTTYPE2.LLT_MEMBERHIERARCHY; - return VSConstants.S_OK; - } - - #endregion - } - - class NodeEnumerator : IVsEnumNavInfoNodes where T : IVsNavInfoNode { - private readonly List _locations; - private IEnumerator _locationEnum; - - public NodeEnumerator(List locations) { - _locations = locations; - Reset(); - } - - #region IVsEnumNavInfoNodes Members - - public int Clone(out IVsEnumNavInfoNodes ppEnum) { - ppEnum = new NodeEnumerator(_locations); - return VSConstants.S_OK; - } - - public int Next(uint celt, IVsNavInfoNode[] rgelt, out uint pceltFetched) { - pceltFetched = 0; - while (celt-- != 0 && _locationEnum.MoveNext()) { - rgelt[pceltFetched++] = _locationEnum.Current; - } - return VSConstants.S_OK; - } - - public int Reset() { - _locationEnum = _locations.GetEnumerator(); - return VSConstants.S_OK; - } - - public int Skip(uint celt) { - while (celt-- != 0) { - _locationEnum.MoveNext(); - } - return VSConstants.S_OK; - } - - #endregion - } - - private void UpdateStatusForIncompleteAnalysis() { - var statusBar = (IVsStatusbar)CommonPackage.GetGlobalService(typeof(SVsStatusbar)); - var analyzer = _textView.GetAnalyzer(); - if (analyzer != null && analyzer.IsAnalyzing) { - statusBar.SetText("Node.js source analysis is not up to date"); - } - } - public int QueryStatus(ref Guid pguidCmdGroup, uint cCmds, OLECMD[] prgCmds, IntPtr pCmdText) { if (pguidCmdGroup == VSConstants.GUID_VSStandardCommandSet97) { for (int i = 0; i < cCmds; i++) {