Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/monodevelop.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGreg Munn <gregm@microsoft.com>2020-01-21 22:48:21 +0300
committerGitHub <noreply@github.com>2020-01-21 22:48:21 +0300
commitd184f327b5ff4069517665a161fa9e48b2e8913d (patch)
treedb946418f5636b5dcb9d77504cbca5c332afc356
parent6a92a4f2b72e0a8537f7ecd81e9d39c4316762f5 (diff)
parentf71636b585019ec97643b98ffd5701f8b5b21b40 (diff)
Merge pull request #9429 from mono/jstedfast-debugger-sourcelink-in-nosourceview
[Debugger] Move the Download-via-SourceLink prompt into the NoSourceV…
-rw-r--r--main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/DebuggingService.cs9
-rw-r--r--main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/Initializer.cs116
-rw-r--r--main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/NoSourceView.cs266
3 files changed, 256 insertions, 135 deletions
diff --git a/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/DebuggingService.cs b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/DebuggingService.cs
index 8fb53e652f..d92f35181a 100644
--- a/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/DebuggingService.cs
+++ b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/DebuggingService.cs
@@ -26,6 +26,11 @@
//
//
+/*
+ * Some places we should be doing some error handling we used to toss
+ * exceptions, now we error out silently, this needs a real solution.
+ */
+
using System;
using System.Xml;
using System.Linq;
@@ -39,8 +44,8 @@ using Mono.Addins;
using Mono.Debugging.Client;
-using Microsoft.VisualStudio.Text;
using Microsoft.CodeAnalysis.Text;
+using Microsoft.VisualStudio.Text;
using MonoDevelop.Ide;
using MonoDevelop.Core;
@@ -48,8 +53,8 @@ using MonoDevelop.Ide.Gui;
using MonoDevelop.Projects;
using MonoDevelop.Components;
using MonoDevelop.Core.Execution;
-using MonoDevelop.Ide.TextEditing;
using MonoDevelop.Ide.Gui.Content;
+using MonoDevelop.Ide.TextEditing;
using MonoDevelop.Debugger.Viewers;
using MonoDevelop.Core.Instrumentation;
diff --git a/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/Initializer.cs b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/Initializer.cs
index f33ea3148d..b4ea663cd5 100644
--- a/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/Initializer.cs
+++ b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/Initializer.cs
@@ -26,16 +26,17 @@
//
using System;
-using MonoDevelop.Ide.Gui;
-using MonoDevelop.Components.Commands;
-using Mono.Debugging.Client;
-using MonoDevelop.Ide.Commands;
-using MonoDevelop.Core;
-using MonoDevelop.Ide;
using System.IO;
+using System.Threading.Tasks;
+
+using Mono.Debugging.Client;
-using Xwt;
+using MonoDevelop.Ide;
+using MonoDevelop.Core;
+using MonoDevelop.Ide.Gui;
using MonoDevelop.Core.Web;
+using MonoDevelop.Ide.Commands;
+using MonoDevelop.Components.Commands;
namespace MonoDevelop.Debugger
{
@@ -68,41 +69,40 @@ namespace MonoDevelop.Debugger
async void OnFrameChanged (object s, EventArgs a)
{
- if (changingFrame) {
+ if (changingFrame)
return;
- }
+
+ changingFrame = true;
+
try {
- changingFrame = true;
if (disassemblyDoc != null && DebuggingService.IsFeatureSupported (DebuggerFeatures.Disassembly))
disassemblyView.Update ();
var frame = DebuggingService.CurrentFrame;
- if (frame == null) {
+ if (frame == null)
return;
- }
+ var debuggerOptions = DebuggingService.GetUserOptions ();
FilePath file = frame.SourceLocation.FileName;
-
int line = frame.SourceLocation.Line;
+
if (line != -1) {
if (!file.IsNullOrEmpty && File.Exists (file)) {
var doc = await IdeApp.Workbench.OpenDocument (file, null, line, 1, OpenDocumentOptions.Debugger);
- if (doc != null) {
+ if (doc != null)
return;
- }
}
- bool alternateLocationExists = false;
+
if (frame.SourceLocation.FileHash != null) {
var newFilePath = SourceCodeLookup.FindSourceFile (file, frame.SourceLocation.FileHash);
if (newFilePath != null && File.Exists (newFilePath)) {
frame.UpdateSourceFile (newFilePath);
var doc = await IdeApp.Workbench.OpenDocument (newFilePath, null, line, 1, OpenDocumentOptions.Debugger);
- if (doc != null) {
+ if (doc != null)
return;
- }
}
}
- var debuggerOptions = DebuggingService.GetUserOptions ();
+
var automaticSourceDownload = debuggerOptions.AutomaticSourceLinkDownload;
var sourceLink = frame.SourceLocation.SourceLink;
@@ -111,53 +111,23 @@ namespace MonoDevelop.Debugger
Document doc = null;
// ~/Library/Caches/VisualStudio/8.0/Symbols/org/projectname/git-sha/path/to/file.cs
if (!File.Exists (downloadLocation)) {
- if (automaticSourceDownload == AutomaticSourceDownload.Always) {
- doc = await DownloadAndOpenFileAsync (frame, line, sourceLink);
- } else {
- var hyperlink = $"<a href='{ sourceLink.Uri }'>{ Path.GetFileName (sourceLink.RelativeFilePath) }</a>";
- var stackframeText = $"<b>{frame.FullStackframeText}</b>";
-
- var text = GettextCatalog.GetString
- ("{0} is a call to external source code. Would you like to get '{1}' and view it?", stackframeText, hyperlink);
- var message = new Ide.GenericMessage {
- Text = GettextCatalog.GetString ("External source code available"),
- SecondaryText = text
- };
- message.AddOption (nameof (automaticSourceDownload), GettextCatalog.GetString ("Always get source code automatically"), false);
- message.Buttons.Add (AlertButton.Cancel);
- message.Buttons.Add (new AlertButton (GettextCatalog.GetString ("Get and Open")));
- message.DefaultButton = 1;
-
- var didNotCancel = MessageService.GenericAlert (message) != AlertButton.Cancel;
- if (didNotCancel) {
- if (message.GetOptionValue (nameof (automaticSourceDownload))) {
- debuggerOptions.AutomaticSourceLinkDownload = AutomaticSourceDownload.Always;
- DebuggingService.SetUserOptions (debuggerOptions);
- }
- doc = await DownloadAndOpenFileAsync (frame, line, sourceLink);
- }
- }
+ if (automaticSourceDownload == AutomaticSourceDownload.Always)
+ doc = await NoSourceView.DownloadAndOpenAsync (frame);
} else {
// The file has previously been downloaded for a different solution.
// We need to map the cached location
frame.UpdateSourceFile (downloadLocation);
doc = await IdeApp.Workbench.OpenDocument (downloadLocation, null, line, 1, OpenDocumentOptions.Debugger);
}
- if (doc != null) {
+ if (doc != null)
return;
- }
}
}
- bool disassemblyNotSupported = false;
- // If we don't have an address space, we can't disassemble
- if (string.IsNullOrEmpty (frame.AddressSpace))
- disassemblyNotSupported = true;
-
- if (!DebuggingService.CurrentSessionSupportsFeature (DebuggerFeatures.Disassembly))
- disassemblyNotSupported = true;
+ bool disassemblySupported = !string.IsNullOrEmpty (frame.AddressSpace) &&
+ DebuggingService.CurrentSessionSupportsFeature (DebuggerFeatures.Disassembly);
- if (disassemblyNotSupported && disassemblyDoc != null) {
+ if (!disassemblySupported && disassemblyDoc != null) {
disassemblyDoc.Close ().Ignore ();
disassemblyDoc = null;
disassemblyView = null;
@@ -167,14 +137,14 @@ namespace MonoDevelop.Debugger
if (disassemblyDoc == null) {
if (noSourceDoc == null) {
noSourceView = new NoSourceView ();
- noSourceView.Update (disassemblyNotSupported);
+ noSourceView.Update (debuggerOptions, frame, disassemblySupported);
noSourceDoc = await IdeApp.Workbench.OpenDocument (noSourceView, true);
noSourceDoc.Closed += delegate {
noSourceDoc = null;
noSourceView = null;
};
} else {
- noSourceView.Update (disassemblyNotSupported);
+ noSourceView.Update (debuggerOptions, frame, disassemblySupported);
noSourceDoc.Select ();
}
} else {
@@ -185,34 +155,6 @@ namespace MonoDevelop.Debugger
}
}
- async System.Threading.Tasks.Task<Document> DownloadAndOpenFileAsync (StackFrame frame, int line, SourceLink sourceLink)
- {
- var pm = IdeApp.Workbench.ProgressMonitors.GetStatusProgressMonitor (
- GettextCatalog.GetString ("Downloading {0}", sourceLink.Uri),
- Stock.StatusDownload,
- true
- );
-
- Document doc = null;
- try {
- var downloadLocation = sourceLink.GetDownloadLocation (symbolCachePath);
- Directory.CreateDirectory (Path.GetDirectoryName (downloadLocation));
- DocumentRegistry.SkipNextChange (downloadLocation);
- var client = HttpClientProvider.CreateHttpClient (sourceLink.Uri);
- using (var stream = await client.GetStreamAsync (sourceLink.Uri).ConfigureAwait (false))
- using (var fs = new FileStream (downloadLocation, FileMode.Create)) {
- await stream.CopyToAsync (fs).ConfigureAwait (false);
- }
- frame.UpdateSourceFile (downloadLocation);
- doc = await Runtime.RunInMainThread (() => IdeApp.Workbench.OpenDocument (downloadLocation, null, line, 1, OpenDocumentOptions.Debugger));
- } catch (Exception ex) {
- LoggingService.LogInternalError ("Error downloading SourceLink file", ex);
- } finally {
- pm.Dispose ();
- }
- return doc;
- }
-
async void OnShowDisassembly (object s, EventArgs a)
{
if (disassemblyDoc == null) {
@@ -230,11 +172,11 @@ namespace MonoDevelop.Debugger
static void SetSourceCodeFrame ()
{
- Backtrace bt = DebuggingService.CurrentCallStack;
+ var bt = DebuggingService.CurrentCallStack;
if (bt != null) {
for (int n = 0; n < bt.FrameCount; n++) {
- StackFrame sf = bt.GetFrame (n);
+ var sf = bt.GetFrame (n);
if (!sf.IsExternalCode &&
sf.SourceLocation.Line != -1 &&
diff --git a/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/NoSourceView.cs b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/NoSourceView.cs
index c2fbbfff1a..96ff22c23f 100644
--- a/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/NoSourceView.cs
+++ b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/NoSourceView.cs
@@ -23,95 +23,184 @@
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
+
using System;
using System.IO;
-using MonoDevelop.Components;
-using MonoDevelop.Core;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+
+using Xwt;
+
+using Mono.Debugging.Client;
+
using MonoDevelop.Ide;
+using MonoDevelop.Core;
using MonoDevelop.Ide.Gui;
-using Xwt;
+using MonoDevelop.Core.Web;
+using MonoDevelop.Components;
using MonoDevelop.Ide.Gui.Documents;
-using System.Threading;
-using System.Threading.Tasks;
namespace MonoDevelop.Debugger
{
public class NoSourceView : DocumentController
{
- XwtControl xwtControl;
- ScrollView scrollView = new ScrollView ();
+ readonly ScrollView scrollView = new ScrollView ();
+ readonly XwtControl control;
+ DebuggerSessionOptions options;
+ Label manageOptionsLabel;
+ CheckBox sourceLinkCheckbox;
+ Button sourceLinkButton;
+ Label sourceLinkLabel;
+ Button disassemblyButton;
+ Label disassemblyLabel;
+ Button browseButton;
+ StackFrame frame;
+ bool downloading;
+
public NoSourceView ()
{
- xwtControl = new XwtControl (scrollView);
+ control = new XwtControl (scrollView);
}
- public void Update (bool disassemblyNotSupported)
+ public void Update (DebuggerSessionOptions options, StackFrame frame, bool disassemblySupported)
{
- scrollView.Content = CreateContent (disassemblyNotSupported);
+ scrollView.Content = CreateContent (options, frame, disassemblySupported);
}
- Widget CreateContent (bool disassemblyNotSupported)
+ Widget CreateContent (DebuggerSessionOptions options, StackFrame frame, bool disassemblySupported)
{
- var fileName = GetFilename (DebuggingService.CurrentFrame?.SourceLocation?.FileName);
- var box = new VBox ();
- box.Margin = 30;
- box.Spacing = 10;
+ var fileName = GetFilename (frame.SourceLocation?.FileName);
+ this.options = options;
+ this.frame = frame;
+
+ var vbox = new VBox {
+ Spacing = 10,
+ Margin = 30
+ };
+
if (!string.IsNullOrEmpty (fileName)) {
DocumentTitle = GettextCatalog.GetString ("Source Not Found");
- var headerLabel = new Label ();
- headerLabel.Markup = GettextCatalog.GetString ("{0} file not found", $"<b>{fileName}</b>");
- box.PackStart (headerLabel);
- var actionsBox = new HBox ();
- var buttonBrowseAndFind = new Button (GettextCatalog.GetString ("Browse and find {0}", fileName));
- buttonBrowseAndFind.Clicked += OpenFindSourceFileDialog;
- actionsBox.PackStart (buttonBrowseAndFind);
- box.PackStart (actionsBox);
+ var headerLabel = new Label {
+ Markup = GettextCatalog.GetString ("{0} file not found", $"<b>{fileName}</b>")
+ };
+ headerLabel.Font = headerLabel.Font.WithScaledSize (2);
+ vbox.PackStart (headerLabel);
+
+ if (frame.SourceLocation?.SourceLink != null && options.AutomaticSourceLinkDownload == AutomaticSourceDownload.Ask) {
+ var sourceLinkVbox = new VBox {
+ MarginBottom = 20,
+ MarginTop = 10,
+ Spacing = 10,
+ };
+
+ sourceLinkLabel = new Label {
+ Markup = GettextCatalog.GetString ("External source code is available. Would you like to download {0} and view it?", $"<a href=\"clicked\">{fileName}</a>"),
+ Name = "SourceLinkLabel"
+ };
+ sourceLinkLabel.LinkClicked += OnDownloadSourceClicked;
+
+ sourceLinkVbox.PackStart (sourceLinkLabel);
+
+ var sourceLinkHbox = new HBox {
+ Spacing = 10
+ };
+
+ sourceLinkButton = new Button (GettextCatalog.GetString ("Download {0}", fileName));
+ sourceLinkButton.Clicked += OnDownloadSourceClicked;
+ sourceLinkHbox.PackStart (sourceLinkButton);
+
+ sourceLinkCheckbox = new CheckBox (GettextCatalog.GetString ("Always download source code automatically"));
+ sourceLinkHbox.PackStart (sourceLinkCheckbox);
+
+ sourceLinkVbox.PackStart (sourceLinkHbox);
+
+ vbox.PackStart (sourceLinkVbox);
+
+ var separator = new HSeparator ();
+ vbox.PackStart (separator);
+ }
+
+ var buttonBox = new HBox ();
+
+ browseButton = new Button (GettextCatalog.GetString ("Browse…"));
+ browseButton.Clicked += OnBrowseClicked;
+ buttonBox.PackStart (browseButton);
+
+ if (disassemblySupported) {
+ disassemblyButton = new Button (GettextCatalog.GetString ("Go to Disassembly"));
+ disassemblyButton.Clicked += OnGoToDisassemblyClicked;
+ buttonBox.PackStart (disassemblyButton);
+ }
+
+ var hbox = new HBox {
+ MarginTop = 20,
+ Spacing = 10
+ };
+
+ hbox.PackStart (buttonBox);
+
if (IdeApp.ProjectOperations.CurrentSelectedSolution != null) {
- var manageLookupsLabel = new Label ();
- manageLookupsLabel.Markup = GettextCatalog.GetString ("Manage the locations used to find source files in the {0}", "<a href=\"clicked\">" + GettextCatalog.GetString ("Solution Options") + "</a>");
- manageLookupsLabel.LinkClicked += (sender, e) => {
- if (IdeApp.ProjectOperations.CurrentSelectedSolution == null)
- return;
- IdeApp.ProjectOperations.ShowOptions (IdeApp.ProjectOperations.CurrentSelectedSolution, "DebugSourceFiles");
+ manageOptionsLabel = new Label {
+ Markup = GettextCatalog.GetString ("Manage the locations used to find source files in the {0}.", "<a href=\"clicked\">" + GettextCatalog.GetString ("Solution Options") + "</a>"),
+ MarginLeft = 10
};
- box.PackStart (manageLookupsLabel);
+ manageOptionsLabel.LinkClicked += OnManageSolutionOptionsClicked;
+ hbox.PackStart (manageOptionsLabel);
}
- headerLabel.Font = headerLabel.Font.WithScaledSize (2);
+
+ vbox.PackStart (hbox);
} else {
DocumentTitle = GettextCatalog.GetString ("Source Not Available");
var headerLabel = new Label (GettextCatalog.GetString ("Source Not Available"));
- box.PackStart (headerLabel);
+ vbox.PackStart (headerLabel);
var label = new Label (GettextCatalog.GetString ("Source information is missing from the debug information for this module"));
- box.PackStart (label);
headerLabel.Font = label.Font.WithScaledSize (2);
+ vbox.PackStart (label);
+
+ if (disassemblySupported) {
+ disassemblyLabel = new Label {
+ Markup = GettextCatalog.GetString ("View disassembly in the {0}", "<a href=\"clicked\">" + GettextCatalog.GetString ("Disassembly Tab") + "</a>")
+ };
+ disassemblyLabel.LinkClicked += OnGoToDisassemblyClicked;
+ vbox.PackStart (disassemblyLabel);
+ }
}
- if (!disassemblyNotSupported) {
- var labelDisassembly = new Label ();
- labelDisassembly.Markup = GettextCatalog.GetString ("View disassembly in the {0}", "<a href=\"clicked\">" + GettextCatalog.GetString ("Disassembly Tab") + "</a>");
- labelDisassembly.LinkClicked += (sender, e) => {
- DebuggingService.ShowDisassembly ();
- Document.Close (false).Ignore ();
- };
- box.PackStart (labelDisassembly);
- }
- return box;
+
+ return vbox;
}
string GetFilename (string fileName)
{
if (fileName == null)
return null;
+
var index = fileName.LastIndexOfAny (new char [] { '/', '\\' });
if (index != -1)
return fileName.Substring (index + 1);
+
return fileName;
}
- private async void OpenFindSourceFileDialog (object sender, EventArgs e)
+ void OnGoToDisassemblyClicked (object sender, EventArgs e)
+ {
+ DebuggingService.ShowDisassembly ();
+ Document.Close (false).Ignore ();
+ }
+
+ void OnManageSolutionOptionsClicked (object sender, EventArgs e)
+ {
+ if (IdeApp.ProjectOperations.CurrentSelectedSolution == null)
+ return;
+
+ IdeApp.ProjectOperations.ShowOptions (IdeApp.ProjectOperations.CurrentSelectedSolution, "DebugSourceFiles");
+ }
+
+ async void OnBrowseClicked (object sender, EventArgs e)
{
var sf = DebuggingService.CurrentFrame;
if (sf == null) {
- LoggingService.LogWarning ($"CurrentFrame was null in {nameof (OpenFindSourceFileDialog)}");
+ LoggingService.LogWarning ($"CurrentFrame was null in {nameof (OnBrowseClicked)}");
return;
}
var dlg = new Ide.Gui.Dialogs.OpenFileDialog (GettextCatalog.GetString ("File to Open") + " " + sf.SourceLocation.FileName, FileChooserAction.Open) {
@@ -135,6 +224,7 @@ namespace MonoDevelop.Debugger
var doc = await IdeApp.Workbench.OpenDocument (newFilePath, null, sf.SourceLocation.Line, 1, OpenDocumentOptions.Debugger);
if (doc != null) {
+ // close the NoSourceView document tab
await Document.Close (false);
}
}
@@ -146,9 +236,93 @@ namespace MonoDevelop.Debugger
}
}
+ public static async Task<Document> DownloadAndOpenAsync (StackFrame frame)
+ {
+ var symbolCachePath = UserProfile.Current.CacheDir.Combine ("Symbols");
+ var sourceLink = frame.SourceLocation.SourceLink;
+
+ var pm = IdeApp.Workbench.ProgressMonitors.GetStatusProgressMonitor (
+ GettextCatalog.GetString ("Downloading {0}", sourceLink.Uri),
+ Stock.StatusDownload,
+ true
+ );
+
+ Document doc = null;
+ try {
+ var downloadLocation = sourceLink.GetDownloadLocation (symbolCachePath);
+ Directory.CreateDirectory (Path.GetDirectoryName (downloadLocation));
+ DocumentRegistry.SkipNextChange (downloadLocation);
+
+ var client = HttpClientProvider.CreateHttpClient (sourceLink.Uri);
+
+ using (var stream = await client.GetStreamAsync (sourceLink.Uri).ConfigureAwait (false)) {
+ using (var fs = new FileStream (downloadLocation, FileMode.Create))
+ await stream.CopyToAsync (fs).ConfigureAwait (false);
+ }
+
+ frame.UpdateSourceFile (downloadLocation);
+
+ int line = frame.SourceLocation.Line;
+
+ doc = await Runtime.RunInMainThread (() => IdeApp.Workbench.OpenDocument (downloadLocation, null, line, 1, OpenDocumentOptions.Debugger));
+ } catch (Exception ex) {
+ LoggingService.LogInternalError ("Error downloading SourceLink file", ex);
+ } finally {
+ pm.Dispose ();
+ }
+
+ return doc;
+ }
+
+ async void OnDownloadSourceClicked (object sender, EventArgs e)
+ {
+ if (downloading)
+ return;
+
+ downloading = true;
+
+ try {
+ if (sourceLinkCheckbox != null && sourceLinkCheckbox.Active) {
+ options.AutomaticSourceLinkDownload = AutomaticSourceDownload.Always;
+ DebuggingService.SetUserOptions (options);
+ }
+
+ var doc = await DownloadAndOpenAsync (frame);
+
+ if (doc != null) {
+ // close the NoSourceView document tab
+ await Document.Close (false);
+ }
+ } finally {
+ downloading = false;
+ }
+ }
+
protected override Task<Control> OnGetViewControlAsync (CancellationToken token, DocumentViewContent view)
{
- return Task.FromResult<Control> (xwtControl);
+ return Task.FromResult<Control> (control);
+ }
+
+ protected override void OnDispose ()
+ {
+ if (sourceLinkButton != null) {
+ sourceLinkLabel.LinkClicked -= OnDownloadSourceClicked;
+ sourceLinkButton.Clicked -= OnDownloadSourceClicked;
+ }
+
+ if (browseButton != null)
+ browseButton.Clicked -= OnBrowseClicked;
+
+ if (disassemblyButton != null)
+ disassemblyButton.Clicked -= OnGoToDisassemblyClicked;
+
+ if (disassemblyLabel != null)
+ disassemblyLabel.LinkClicked -= OnGoToDisassemblyClicked;
+
+ if (manageOptionsLabel != null)
+ manageOptionsLabel.LinkClicked -= OnManageSolutionOptionsClicked;
+
+ base.OnDispose ();
}
}
}