Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SourceLink] Create output window for logging, and tell the user what is going on #57996

Closed
wants to merge 15 commits into from

Conversation

davidwengier
Copy link
Contributor

@davidwengier davidwengier commented Nov 26, 2021

Fixes #57352
Part of #55834
Includes #57978 so just review 33072b9 (#57996)

The idea is to help library authors work out why their embedded or source link sources might not be working, we can provide this output window. It will also be a good source for us to ask for information from, for feedback issues.

Screenshots:
image

image

@davidwengier
Copy link
Contributor Author

davidwengier commented Dec 1, 2021

Updated. Sorry I had to rebase, and therefore force push, because of changes to the other PR

@davidwengier
Copy link
Contributor Author

Updated. Sorry I had to rebase, and therefore force push, because of changes to the other PR

Just realised I'll probably be rebasing again when that PR merges 🤦‍♂️


public void Clear()
{
_threadingContext.JoinableTaskFactory.Run(async () =>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should these methods be async so we're not potentially blocking up a background thread?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also worry about deadlock risk here if we end up with a UI thread blocking on the call to GetGeneratedFileAsync, and then this trying to hop back. Given this is only logging, should this just be queuing work to the UI thread and we keep the actual updating of the pane asynchronous? It'd remove the deadlock risk, and also would probably help performance so you're not doing so many UI transitions during the main code path.

return _outputPane;
}

private IVsOutputWindowPane? CreateOutputPane(IVsOutputWindow outputWindow)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TryCreate...?

// Try to get the workspace pane if it has already been registered
var workspacePaneGuid = s_outputPaneGuid;

// If the pane has already been created, CreatePane returns it
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment doesn't make sense -- GetPane is returning it...?

Comment on lines +47 to +48
// Despite being named "ThreadSafe" unfortunately OutputStringThreadSafe does not play well with JTF
// which the debugger needs for SourceLink
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The docs for the "ThreadSafe" method imply it's for pumping reasons, and there's some advice about casting to a different interface instead. Should we be doing that?

Comment on lines +52 to +57
if (pane == null)
{
return;
}

pane.OutputStringThreadSafe(value + Environment.NewLine);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pane?.OutputStringThreadSafe...?

@@ -54,22 +54,29 @@ internal sealed class PdbSourceDocumentMetadataAsSourceFileProvider : IMetadataA
if (signaturesOnly)
return null;

var assemblyName = symbol.ContainingAssembly.Identity.Name;

_logger?.Clear();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's implicit we're never doing two calls to GetGeneratedFIleAsync at once?

// If this is a reference assembly then we won't have the right information available, so bail out
// TODO: find the implementation assembly for the reference assembly, and keep going: https://github.com/dotnet/roslyn/issues/55834
var isReferenceAssembly = symbol.ContainingAssembly.GetAttributes().Any(attribute => attribute.AttributeClass?.Name == nameof(ReferenceAssemblyAttribute)
&& attribute.AttributeClass.ToNameDisplayString() == typeof(ReferenceAssemblyAttribute).FullName);
if (isReferenceAssembly)
{
_logger?.Log("");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why?


var compilation = await project.GetRequiredCompilationAsync(cancellationToken).ConfigureAwait(false);

if (compilation.GetMetadataReference(symbol.ContainingAssembly) is not PortableExecutableReference { FilePath: not null and var dllPath })
{
_logger?.Log(FeaturesResources.Source_is_a_reference_assembly);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you mean to put this earlier? The message here should probably be different.

@davidwengier
Copy link
Contributor Author

Closing this. Going to combine with the document tab changes, and add some telemetry, in a follow up since this missed Preview 2 anyway.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[SourceLink] Output window logging
3 participants