Skip to content

Commit

Permalink
Support EditorBrowsable in Fully-Qualify
Browse files Browse the repository at this point in the history
  • Loading branch information
CyrusNajmabadi committed Jul 29, 2021
1 parent b708867 commit a04c693
Show file tree
Hide file tree
Showing 2 changed files with 163 additions and 3 deletions.
151 changes: 151 additions & 0 deletions src/EditorFeatures/CSharpTest/FullyQualify/FullyQualifyTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CodeActions;
using Microsoft.CodeAnalysis.CodeFixes;
using Microsoft.CodeAnalysis.Completion;
using Microsoft.CodeAnalysis.CSharp.CodeFixes.FullyQualify;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Diagnostics;
Expand Down Expand Up @@ -1496,5 +1497,155 @@ await TestInRegularAndScriptAsync(
@"using M = [|Math|]",
@"using M = System.Math");
}

[Fact]
[WorkItem(54544, "https://github.com/dotnet/roslyn/issues/54544")]
public async Task TestAddUsingsEditorBrowsableNeverSameProject()
{
const string InitialWorkspace = @"
<Workspace>
<Project Language=""C#"" AssemblyName=""lib"" CommonReferences=""true"">
<Document FilePath=""lib.cs"">
using System.ComponentModel;
namespace ProjectLib
{
[EditorBrowsable(EditorBrowsableState.Never)]
public class Project
{
}
}
</Document>
<Document FilePath=""Program.cs"">
class Program
{
static void Main(string[] args)
{
Project p = new [|Project()|];
}
}
</Document>
</Project>
</Workspace>";

const string ExpectedDocumentText = @"
class Program
{
static void Main(string[] args)
{
Project p = new [|ProjectLib.Project()|];
}
}
";

await TestInRegularAndScript1Async(InitialWorkspace, ExpectedDocumentText);
}

[Fact]
[WorkItem(54544, "https://github.com/dotnet/roslyn/issues/54544")]
public async Task TestAddUsingsEditorBrowsableNeverDifferentProject()
{
const string InitialWorkspace = @"
<Workspace>
<Project Language=""Visual Basic"" AssemblyName=""lib"" CommonReferences=""true"">
<Document FilePath=""lib.vb"">
imports System.ComponentModel
namespace ProjectLib
&lt;EditorBrowsable(EditorBrowsableState.Never)&gt;
public class Project
end class
end namespace
</Document>
</Project>
<Project Language=""C#"" AssemblyName=""Console"" CommonReferences=""true"">
<ProjectReference>lib</ProjectReference>
<Document FilePath=""Program.cs"">
class Program
{
static void Main(string[] args)
{
[|Project|] p = new Project();
}
}
</Document>
</Project>
</Workspace>";
await TestMissingAsync(InitialWorkspace);
}

[Fact]
[WorkItem(54544, "https://github.com/dotnet/roslyn/issues/54544")]
public async Task TestAddUsingsEditorBrowsableAdvancedDifferentProjectOptionOn()
{
const string InitialWorkspace = @"
<Workspace>
<Project Language=""Visual Basic"" AssemblyName=""lib"" CommonReferences=""true"">
<Document FilePath=""lib.vb"">
imports System.ComponentModel
namespace ProjectLib
&lt;EditorBrowsable(EditorBrowsableState.Advanced)&gt;
public class Project
end class
end namespace
</Document>
</Project>
<Project Language=""C#"" AssemblyName=""Console"" CommonReferences=""true"">
<ProjectReference>lib</ProjectReference>
<Document FilePath=""Program.cs"">
class Program
{
static void Main(string[] args)
{
[|Project|] p = new Project();
}
}
</Document>
</Project>
</Workspace>";

const string ExpectedDocumentText = @"
class Program
{
static void Main(string[] args)
{
ProjectLib.Project p = new Project();
}
}
";
await TestInRegularAndScript1Async(InitialWorkspace, ExpectedDocumentText);
}

[Fact]
[WorkItem(54544, "https://github.com/dotnet/roslyn/issues/54544")]
public async Task TestAddUsingsEditorBrowsableAdvancedDifferentProjectOptionOff()
{
const string InitialWorkspace = @"
<Workspace>
<Project Language=""Visual Basic"" AssemblyName=""lib"" CommonReferences=""true"">
<Document FilePath=""lib.vb"">
imports System.ComponentModel
namespace ProjectLib
&lt;EditorBrowsable(EditorBrowsableState.Advanced)&gt;
public class Project
end class
end namespace
</Document>
</Project>
<Project Language=""C#"" AssemblyName=""Console"" CommonReferences=""true"">
<ProjectReference>lib</ProjectReference>
<Document FilePath=""Program.cs"">
class Program
{
static void Main(string[] args)
{
[|Project|] p = new Project();
}
}
</Document>
</Project>
</Workspace>";

await TestMissingAsync(InitialWorkspace, new TestParameters(
options: Option(CompletionOptions.HideAdvancedMembers, true)));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,14 @@
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CodeActions;
using Microsoft.CodeAnalysis.Completion;
using Microsoft.CodeAnalysis.FindSymbols;
using Microsoft.CodeAnalysis.Internal.Log;
using Microsoft.CodeAnalysis.LanguageServices;
using Microsoft.CodeAnalysis.Shared.Extensions;
using Microsoft.CodeAnalysis.Shared.Utilities;
using Roslyn.Utilities;
using static Microsoft.CodeAnalysis.Shared.Utilities.EditorBrowsableHelpers;

namespace Microsoft.CodeAnalysis.CodeFixes.FullyQualify
{
Expand Down Expand Up @@ -62,7 +65,7 @@ public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)

var semanticModel = await document.GetRequiredSemanticModelAsync(cancellationToken).ConfigureAwait(false);

var matchingTypes = await GetMatchingTypesAsync(project, semanticModel, node, cancellationToken).ConfigureAwait(false);
var matchingTypes = await GetMatchingTypesAsync(document, semanticModel, node, cancellationToken).ConfigureAwait(false);
var matchingNamespaces = await GetMatchingNamespacesAsync(project, semanticModel, node, cancellationToken).ConfigureAwait(false);

if (matchingTypes.IsEmpty && matchingNamespaces.IsEmpty)
Expand Down Expand Up @@ -144,10 +147,11 @@ private async Task<Document> ProcessNodeAsync(Document document, SyntaxNode node
}

private async Task<ImmutableArray<SymbolResult>> GetMatchingTypesAsync(
Project project, SemanticModel semanticModel, SyntaxNode node, CancellationToken cancellationToken)
Document document, SemanticModel semanticModel, SyntaxNode node, CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();

var project = document.Project;
var syntaxFacts = project.LanguageServices.GetRequiredService<ISyntaxFactsService>();

syntaxFacts.GetNameAndArityOfSimpleName(node, out var name, out var arity);
Expand All @@ -167,9 +171,14 @@ private async Task<ImmutableArray<SymbolResult>> GetMatchingTypesAsync(
symbols = symbols.Concat(attributeSymbols);
}

var options = await document.GetOptionsAsync(cancellationToken).ConfigureAwait(false);
var hideAdvancedMembers = options.GetOption(CompletionOptions.HideAdvancedMembers);
var editorBrowserInfo = new EditorBrowsableInfo(semanticModel.Compilation);

var validSymbols = symbols
.OfType<INamedTypeSymbol>()
.Where(s => IsValidNamedTypeSearchResult(semanticModel, arity, inAttributeContext, looksGeneric, s))
.Where(s => IsValidNamedTypeSearchResult(semanticModel, arity, inAttributeContext, looksGeneric, s) &&
s.IsEditorBrowsable(hideAdvancedMembers, semanticModel.Compilation, editorBrowserInfo))
.ToImmutableArray();

// Check what the current node binds to. If it binds to any symbols, but with
Expand Down

0 comments on commit a04c693

Please sign in to comment.