[svn] r6816: vs-plugin/trunk: Nemerle.Compiler.Utils/Nemerle.Completion2/CodeModel/GotoInfo.n Nemerle.Comp...

pbludov svnadmin at nemerle.org
Wed Nov 1 08:31:47 CET 2006


Log:
Select location dialog for Goto.

Author: pbludov
Date: Wed Nov  1 08:31:43 2006
New Revision: 6816

Modified:
   vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeModel/GotoInfo.n
   vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeModel/Project.Type.n
   vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeModel/Project.n
   vs-plugin/trunk/Nemerle.VsIntegration/LanguageService/NemerleAuthoringScope.cs
   vs-plugin/trunk/Nemerle.VsIntegration/Project/ProjectInfo.cs

Modified: vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeModel/GotoInfo.n
==============================================================================
--- vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeModel/GotoInfo.n	(original)
+++ vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeModel/GotoInfo.n	Wed Nov  1 08:31:43 2006
@@ -17,6 +17,11 @@
     [Accessor] mutable _colEnd    : int;
     [Accessor] mutable _member    : System.Reflection.MemberInfo;
 
+    public this(location : Location)
+    {
+      SetLocation(location);
+    }
+
     public this(member : IMember)
     {
       SetLocation(member.Location);
@@ -43,12 +48,6 @@
       SetLocation(value.Location);
     }
 
-    public this(tv : TyVar)
-    {
-    | MType.Class(tycon, _) => SetLocation(tycon.Location);
-    | _ => ()
-    }
-
     public this(_fh : Typedtree.Fun_header)
     {
     }
@@ -64,11 +63,16 @@
 
     private SetLocation(location : Location) : void
     {
-      _filePath  = location.File;
-      _lineStart = location.Line      - 1;
-      _colStart  = location.Column    - 1;
-      _lineEnd   = location.EndLine   - 1;
-      _colEnd    = location.EndColumn - 1;
+      SetLocation(location.File, location.Line, location.Column, location.EndLine, location.EndColumn)
+    }
+
+    public SetLocation(filePath : string, lineStart : int, colStart : int, lineEnd : int, colEnd : int) : void
+    {
+      _filePath  = filePath;
+      _lineStart = lineStart - 1;
+      _colStart  = colStart  - 1;
+      _lineEnd   = lineEnd   - 1;
+      _colEnd    = colEnd    - 1;
 
       when (_lineStart < _lineEnd)
       {
@@ -81,5 +85,17 @@
     {
       get { !string.IsNullOrEmpty(_filePath) && _lineEnd >= 0 }
     }
+
+    public override ToString() : string
+    {
+      if (_lineEnd >= 0)
+        string.Format("{0} {1}:{2} {3}:{4}", _filePath, _lineStart, _colStart, _lineEnd, _colEnd);
+      else if (string.IsNullOrEmpty(_filePath))
+        "<unknown>";
+      else
+        _filePath;
+      }
+    }
+
   }
 }

Modified: vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeModel/Project.Type.n
==============================================================================
--- vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeModel/Project.Type.n	(original)
+++ vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeModel/Project.Type.n	Wed Nov  1 08:31:43 2006
@@ -3,6 +3,7 @@
 using System.Diagnostics;
 
 using Nemerle.Assertions;
+using Nemerle.Collections;
 using Nemerle.Compiler;
 using Nemerle.Compiler.Utils;
 using Nemerle.Compiler.Parsetree;
@@ -89,6 +90,14 @@
             // Ýňîň ęîä âűëĺňŕĺň ďî NulReferenceException ĺńëč, íŕďđčěĺđ, íŕâĺńňč 
             // ęóđńîđ íŕ "Message_output" â ńňđîęĺ 46 ôŕéëŕ:
             // Nemerle.Compiler.Utils\Nemerle.Completion2\Engine\Engine.Properties.n
+
+            // PB061101: Çŕáčë ďîęŕ ęîńňűëü ÷ňîáű đŕáîňŕëî.
+            if (m1 == null)
+              m2
+            else if (m2 == null)
+              m1
+            else
+            {
             def loc1 = m1.Location;
             def loc2 = m2.Location;
 
@@ -96,6 +105,7 @@
               if (m2 is PropertyBuilder) m2 else m1
             else
               if (loc1.Intersect(loc2) == loc1) m1 else m2
+            }
           });
 
       match (member)
@@ -175,21 +185,31 @@
       col       : int,
       source    : ISourceTextManager
     )
-      : GotoInfo
+      : list [GotoInfo]
     {
       def (_, _, tObj) = FindObject(typeDecl, fileIndex, line, col, source);
 
       match (tObj)
       {
-      | me is TExpr.MacroEnvelope  => (GotoInfo(me))
-      | lv is LocalValue           => (GotoInfo(lv))
-      | tv is TyVar                => (GotoInfo(tv))
-      | fh is Typedtree.Fun_header => (GotoInfo(fh))
-      | fb is FieldBuilder         => (GotoInfo(fb))
-      | pb is PropertyBuilder      => (GotoInfo(pb))
-      | mm is IMember              => (GotoInfo(mm))
-      | tb is TypeBuilder          => (GotoInfo(tb))
-      | _                          => (null)
+      | me is TExpr.MacroEnvelope  => [(GotoInfo(me))]
+      | lv is LocalValue           => [(GotoInfo(lv))]
+      | tv is TyVar                =>
+        match (tv)
+        {
+          | MType.Class(tycon is TypeBuilder, _) =>
+            List.Map(tycon.PartsLocation, GotoInfo);
+          | MType.Class(tycon, _) =>
+            List.Map(tycon.GetMembers(BindingFlags.Static 
+              %| BindingFlags.Instance %| BindingFlags.Public 
+              %| BindingFlags.NonPublic %| BindingFlags.DeclaredOnly), GotoInfo);
+          | _ => []
+        }
+      | tb is TypeBuilder          => List.Map(tb.PartsLocation, GotoInfo);
+      | fh is Typedtree.Fun_header => [(GotoInfo(fh))]
+      | fb is FieldBuilder         => [(GotoInfo(fb))]
+      | pb is PropertyBuilder      => [(GotoInfo(pb))]
+      | mm is IMember              => [(GotoInfo(mm))]
+      | _                          => []
       }
     }
 

Modified: vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeModel/Project.n
==============================================================================
--- vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeModel/Project.n	(original)
+++ vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeModel/Project.n	Wed Nov  1 08:31:43 2006
@@ -142,14 +142,14 @@
                 col      : int,
       [NotNull] source   : ISourceTextManager
     )
-      : GotoInfo
+      : array [GotoInfo]
     {
       def fileIndex = _compileUnits.GetFileIndex(filePath);
       def decl      = GetActiveDecl(fileIndex, line, col);
 
       match (decl)
       {
-      | Type as tp => GetTypeGoto(tp, fileIndex, line, col, source);
+      | Type as tp => GetTypeGoto(tp, fileIndex, line, col, source).ToArray();
       | None       => throw System.Exception()
       | _ => null
       }

Modified: vs-plugin/trunk/Nemerle.VsIntegration/LanguageService/NemerleAuthoringScope.cs
==============================================================================
--- vs-plugin/trunk/Nemerle.VsIntegration/LanguageService/NemerleAuthoringScope.cs	(original)
+++ vs-plugin/trunk/Nemerle.VsIntegration/LanguageService/NemerleAuthoringScope.cs	Wed Nov  1 08:31:43 2006
@@ -1,7 +1,9 @@
 using System;
+using System.Diagnostics;
+using System.IO;
 using System.Runtime.InteropServices;
 using System.Diagnostics.SymbolStore;
-
+using System.Windows.Forms;
 using Microsoft.VisualStudio;
 using Microsoft.VisualStudio.Package;
 using Microsoft.VisualStudio.TextManager.Interop;
@@ -85,54 +87,60 @@
 		{
 			span = new TextSpan();
 
-			GotoInfo info = _project.GetGoto(_filePath, line, col, _sourceText);
-
-			if (info == null)
-				return null;
+			GotoInfo[] info = _project.GetGoto(_filePath, line, col, _sourceText);
 
-			if (info.HasLocation)
+			if (info == null || info.Length == 0)
 			{
-				span.iStartLine  = info.LineStart;
-				span.iEndLine    = info.LineEnd;
-				span.iStartIndex = info.ColStart;
-				span.iEndIndex   = info.ColEnd;
-
-				return info.FilePath;
+				// Not implemented nor expected
+				//
+				return null;
 			}
 
-			if (info.Member != null && !string.IsNullOrEmpty(info.FilePath))
+			ISymbolBinder1    binder     = null;
+			IntPtr            mdiPtr     = IntPtr.Zero;
+			ISymbolDocument[] documents  = null;
+			int[]             lines      = null;
+			int[]             columns    = null;
+			int[]             endLines   = null;
+			int[]             endColumns = null;
+
+			try
+			{
+				foreach (GotoInfo gotoInfo in info)
+				{
+					if (gotoInfo.HasLocation)
+						continue;
+					if (gotoInfo.Member == null || string.IsNullOrEmpty(gotoInfo.FilePath))
+						continue;
+
+					// First time init
+					//
+					if (mdiPtr == IntPtr.Zero)
 			{
 				Guid   mdiGuid = new Guid("7DAC8207-D3AE-4c75-9B67-92801A497D44");
-				IntPtr mdiPtr  = IntPtr.Zero;
 				object mdiUnk;
 
-				if (VSConstants.S_OK == _project.SmartOpenScope.OpenScope(info.FilePath, 0, ref mdiGuid, out mdiUnk))
-				{
-					try
+						if (VSConstants.S_OK == _project.SmartOpenScope.OpenScope(info[0].FilePath, 0, ref mdiGuid, out mdiUnk))
 					{
 						mdiPtr                = Marshal.GetIUnknownForObject(mdiUnk);
+							binder     = new SymBinder();
+							documents  = new ISymbolDocument[1];
+							lines      = new int[1];
+							columns    = new int[1];
+							endLines   = new int[1];
+							endColumns = new int[1];
+						}
+					}
 
-						SymbolToken    token  = new SymbolToken(info.Member.MetadataToken);
-						ISymbolBinder1 binder = new SymBinder();
-						ISymbolReader  reader = binder.GetReader(mdiPtr, info.FilePath, null);
+					SymbolToken    token  = new SymbolToken(gotoInfo.Member.MetadataToken);
+					ISymbolReader  reader = binder.GetReader(mdiPtr, gotoInfo.FilePath, null);
 						ISymbolMethod  method = reader.GetMethod(token);
 
 						if (method.SequencePointCount > 0)
 						{
-							ISymbolDocument[] documents  = new ISymbolDocument[1];
-							int[]             lines      = new int[1];
-							int[]             columns    = new int[1];
-							int[]             endLines   = new int[1];
-							int[]             endColumns = new int[1];
-
 							method.GetSequencePoints(new int[1], documents, lines, columns, endLines, endColumns);
-
-							span.iStartLine  = lines[0]    - 1;
-							span.iEndLine    = endLines[0] - 1;
-							span.iStartIndex = columns[0]  - 1;
-							span.iEndIndex   = columns[0]  - 1;
-
-							return documents[0].URL;
+						gotoInfo.SetLocation(documents[0].URL, lines[0], columns[0], endLines[0], endColumns[0]);
+					}
 						}
 					}
 					catch (COMException)
@@ -144,6 +152,106 @@
 						if (IntPtr.Zero != mdiPtr)
 							Marshal.Release(mdiPtr);
 					}
+
+			if (info.Length == 1)
+			{
+				if (info[0].HasLocation)
+				{
+					span.iStartLine  = info[0].LineStart;
+					span.iEndLine    = info[0].LineEnd;
+					span.iStartIndex = info[0].ColStart;
+					span.iEndIndex   = info[0].ColEnd;
+
+					return info[0].FilePath;
+				}
+			}
+			else
+			{
+				// TODO: Âűíĺńňč âĺńü UI ęóäŕ ďîäŕëüřĺ.
+				// TODO: Âű÷čńëčňü őîň˙ áű HWND TextEditor'ŕ čëč őîň˙ áű ăëŕâíîăî îęíŕ ńňóäčč.
+
+				Form     popup = new Form();
+				ListView lv    = new ListView();
+				ColumnHeader colFile = new ColumnHeader();
+				ColumnHeader colLine = new ColumnHeader();
+				ColumnHeader colPath = new ColumnHeader();
+
+				popup.StartPosition = FormStartPosition.CenterScreen;
+				popup.ShowInTaskbar = false;
+				popup.Text = "Select location:";
+				popup.FormBorderStyle = FormBorderStyle.FixedToolWindow;
+				popup.Controls.Add(lv);
+				popup.Width = 600;
+				popup.Load += delegate(object sender, EventArgs e)
+				{
+					Form form = ((Form)sender);
+					foreach (ColumnHeader hdr in ((ListView)form.Controls[0]).Columns)
+						hdr.AutoResize(ColumnHeaderAutoResizeStyle.ColumnContent);
+				};
+
+				lv.BorderStyle = BorderStyle.None;
+				lv.Dock = DockStyle.Fill;
+				lv.View = View.Details;
+				lv.ShowItemToolTips = true;
+				lv.FullRowSelect = true;
+				lv.Columns.AddRange(new ColumnHeader[]{colFile, colLine, colPath});
+
+				foreach (GotoInfo gotoInfo in info)
+				{
+					if (gotoInfo.HasLocation)
+					{
+						ListViewItem lvi = new ListViewItem(new string[]{Path.GetFileName(gotoInfo.FilePath), gotoInfo.LineStart.ToString(), Path.GetDirectoryName(gotoInfo.FilePath)});
+						lvi.Tag = gotoInfo;
+						lv.Items.Add(lvi);
+					}
+				}
+
+				if (lv.Items.Count == 0)
+				{
+					// Sorry guys, the .pdb file is missing.
+					//
+					return null;
+				}
+
+				lv.KeyPress += delegate(object sender, KeyPressEventArgs e)
+				{
+					Control ctl   = sender as Control;
+					Form    owner = ctl.FindForm();
+
+					if (e.KeyChar == (char) Keys.Escape)
+						owner.DialogResult = DialogResult.Cancel;
+					else if (e.KeyChar == '\r' || e.KeyChar == ' ')
+						owner.DialogResult = DialogResult.OK;
+					else
+						return;
+
+					owner.Close();
+				};
+				lv.DoubleClick += delegate(object sender, EventArgs e)
+				{
+					Control ctl   = sender as Control;
+					Form    owner = ctl.FindForm();
+
+					owner.DialogResult = DialogResult.OK;
+					owner.Close();
+				};
+
+				colFile.Text = "File";
+				colLine.Text = "Line";
+				colPath.Text = "Path";
+
+				if (DialogResult.OK == popup.ShowDialog())
+				{
+					if (null != lv.SelectedItems[0])
+					{
+						GotoInfo selectedFile = (GotoInfo)lv.SelectedItems[0].Tag;
+						span.iStartLine  = selectedFile.LineStart;
+						span.iEndLine    = selectedFile.LineEnd;
+						span.iStartIndex = selectedFile.ColStart;
+						span.iEndIndex   = selectedFile.ColEnd;
+
+						return selectedFile.FilePath;
+					}
 				}
 			}
 

Modified: vs-plugin/trunk/Nemerle.VsIntegration/Project/ProjectInfo.cs
==============================================================================
--- vs-plugin/trunk/Nemerle.VsIntegration/Project/ProjectInfo.cs	(original)
+++ vs-plugin/trunk/Nemerle.VsIntegration/Project/ProjectInfo.cs	Wed Nov  1 08:31:43 2006
@@ -363,7 +363,7 @@
 			return info;
 		}
 
-		public GotoInfo GetGoto(string filePath, int line, int col, ISourceTextManager source)
+		public GotoInfo[] GetGoto(string filePath, int line, int col, ISourceTextManager source)
 		{
 			ErrorHelper.ThrowIfPathNullOrEmpty(filePath, "filePath");
 			return Project.GetGotoInfo(filePath, line + 1, col + 1, source);



More information about the svn mailing list