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

Exclude Misc project from InternalsVisibleTo completion #1902

Merged
merged 9 commits into from
Aug 20, 2020
1 change: 1 addition & 0 deletions src/OmniSharp.Abstractions/Configuration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ internal static class Configuration
public readonly static string RoslynFeatures = GetRoslynAssemblyFullName("Microsoft.CodeAnalysis.Features");
public readonly static string RoslynCSharpFeatures = GetRoslynAssemblyFullName("Microsoft.CodeAnalysis.CSharp.Features");
public readonly static string RoslynWorkspaces = GetRoslynAssemblyFullName("Microsoft.CodeAnalysis.Workspaces");
public readonly static string OmniSharpMiscProjectName = "OmniSharpMiscellaneousFiles";

private static string GetRoslynAssemblyFullName(string name)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Resolvers;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Completion;
using Microsoft.CodeAnalysis.Tags;
Expand Down Expand Up @@ -150,7 +151,7 @@ public async Task<CompletionResponse> Handle(CompletionRequest request)
}

var triggerCharactersBuilder = ImmutableArray.CreateBuilder<char>(completions.Rules.DefaultCommitCharacters.Length);
var completionsBuilder = ImmutableArray.CreateBuilder<CompletionItem>(completions.Items.Length);
var completionsBuilder = new List<CompletionItem>();
filipw marked this conversation as resolved.
Show resolved Hide resolved

// If we don't encounter any unimported types, and the completion context thinks that some would be available, then
// that completion provider is still creating the cache. We'll mark this completion list as not completed, and the
Expand All @@ -175,6 +176,8 @@ public async Task<CompletionResponse> Handle(CompletionRequest request)
// The IVT completer doesn't add extra things before the completion
// span, only assembly keys at the end if they exist.
{
// if the completion is for the hidden Misc files project, skip it
if (completion.DisplayText == Configuration.OmniSharpMiscProjectName) continue;
CompletionChange change = await completionService.GetChangeAsync(document, completion);
Debug.Assert(typedSpan == change.TextChange.Span);
insertText = change.TextChange.NewText!;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,15 +49,10 @@ static CompletionItemExtensions()
_getChangeAsync = typeof(CompletionService).GetMethod(nameof(GetChangeAsync), BindingFlags.NonPublic | BindingFlags.Instance);
}

internal static string GetProviderName(this CompletionItem item)
{
return (string)_getProviderName.GetValue(item);
}
internal static string GetProviderName(this CompletionItem item) => (string)_getProviderName.GetValue(item);

public static bool IsObjectCreationCompletionItem(this CompletionItem item) => GetProviderName(item) == ObjectCreationCompletionProvider;

public static bool IsObjectCreationCompletionItem(this CompletionItem item)
{
return GetProviderName(item) == ObjectCreationCompletionProvider;
}
public static Task<(CompletionList completionList, bool expandItemsAvailable)> GetCompletionsInternalAsync(
this CompletionService completionService,
Document document,
Expand Down Expand Up @@ -109,10 +104,7 @@ public static bool UseDisplayTextAsCompletionText(this CompletionItem completion
return provider == NamedParameterCompletionProvider || provider == OverrideCompletionProvider || provider == PartialMethodCompletionProvider;
}

public static bool TryGetInsertionText(this CompletionItem completionItem, out string insertionText)
{
return completionItem.Properties.TryGetValue(InsertionText, out insertionText);
}
public static bool TryGetInsertionText(this CompletionItem completionItem, out string insertionText) => completionItem.Properties.TryGetValue(InsertionText, out insertionText);

public static AutoCompleteResponse ToAutoCompleteResponse(this CompletionItem item, bool wantKind, bool isSuggestionMode, bool preselect)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -163,8 +163,8 @@ public async Task<ImmutableArray<DocumentDiagnostics>> GetDiagnostics(ImmutableA
private static async Task<ImmutableArray<Diagnostic>> GetDiagnosticsForDocument(Document document, string projectName)
{
// Only basic syntax check is available if file is miscellanous like orphan .cs file.
// Those projects are on hard coded virtual project named 'MiscellaneousFiles.csproj'.
if (projectName == "MiscellaneousFiles.csproj")
// Those projects are on hard coded virtual project
if (projectName == $"{Configuration.OmniSharpMiscProjectName}.csproj")
{
var syntaxTree = await document.GetSyntaxTreeAsync();
return syntaxTree.GetDiagnostics().ToImmutableArray();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -230,8 +230,8 @@ private async Task AnalyzeDocument(Project project, ImmutableArray<DiagnosticAna
var diagnostics = ImmutableArray<Diagnostic>.Empty;

// Only basic syntax check is available if file is miscellanous like orphan .cs file.
// Those projects are on hard coded virtual project named 'MiscellaneousFiles.csproj'.
if (project.Name == "MiscellaneousFiles.csproj")
// Those projects are on hard coded virtual project
if (project.Name == $"{Configuration.OmniSharpMiscProjectName}.csproj")
{
var syntaxTree = await document.GetSyntaxTreeAsync();
diagnostics = syntaxTree.GetDiagnostics().ToImmutableArray();
Expand Down
14 changes: 9 additions & 5 deletions src/OmniSharp.Roslyn/OmniSharpWorkspace.cs
Original file line number Diff line number Diff line change
Expand Up @@ -131,13 +131,13 @@ public void RemoveMetadataReference(ProjectId projectId, MetadataReference metad
OnMetadataReferenceRemoved(projectId, metadataReference);
}

public DocumentId TryAddMiscellaneousDocument(string filePath, string language)
public DocumentId TryAddMiscellaneousDocument(string filePath, TextLoader loader, string language)
{
if (GetDocument(filePath) != null)
return null; //if the workspace already knows about this document then it is not a miscellaneous document

var projectInfo = miscDocumentsProjectInfos.GetOrAdd(language, (lang) => CreateMiscFilesProject(lang));
var documentId = AddDocument(projectInfo.Id, filePath);
var documentId = AddDocument(projectInfo.Id, filePath, loader);
_logger.LogInformation($"Miscellaneous file: {filePath} added to workspace");

if (!EditorConfigEnabled)
Expand All @@ -157,6 +157,11 @@ public DocumentId TryAddMiscellaneousDocument(string filePath, string language)
return documentId;
}

public DocumentId TryAddMiscellaneousDocument(string filePath, string language)
{
return TryAddMiscellaneousDocument(filePath, new OmniSharpTextLoader(filePath), language);
}

public bool TryRemoveMiscellaneousDocument(string filePath)
{
var documentId = GetDocumentId(filePath);
Expand Down Expand Up @@ -214,14 +219,13 @@ public void UpdateCompilationOptionsForProject(ProjectId projectId, CompilationO

private ProjectInfo CreateMiscFilesProject(string language)
{
string assemblyName = Guid.NewGuid().ToString("N");
var projectInfo = ProjectInfo.Create(
id: ProjectId.CreateNewId(),
version: VersionStamp.Create(),
name: "MiscellaneousFiles.csproj",
name: $"{Configuration.OmniSharpMiscProjectName}.csproj",
metadataReferences: DefaultMetadataReferenceHelper.GetDefaultMetadataReferenceLocations()
.Select(loc => MetadataReference.CreateFromFile(loc)),
assemblyName: assemblyName,
assemblyName: Configuration.OmniSharpMiscProjectName,
language: language);

AddProject(projectInfo);
Expand Down
26 changes: 26 additions & 0 deletions tests/OmniSharp.Roslyn.CSharp.Tests/CompletionFacts.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Text;
using Microsoft.Extensions.Logging;
using OmniSharp.Models.v1.Completion;
using OmniSharp.Roslyn.CSharp.Services.Completion;
Expand Down Expand Up @@ -1184,6 +1185,31 @@ public async Task InternalsVisibleToCompletion()
const string input = @"
[assembly: System.Runtime.CompilerServices.InternalsVisibleTo(""$$";

var completions = await FindCompletionsAsync("dummy.cs", input);
Assert.Single(completions.Items);
Assert.Equal("AssemblyNameVal", completions.Items[0].Label);
Assert.Equal("AssemblyNameVal", completions.Items[0].InsertText);
}

[Fact]
public async Task InternalsVisibleToCompletionSkipsMiscProject()
{
var projectInfo = ProjectInfo.Create(
ProjectId.CreateNewId(),
VersionStamp.Create(),
"ProjectNameVal",
"AssemblyNameVal",
LanguageNames.CSharp,
"/path/to/project.csproj");

SharedOmniSharpTestHost.Workspace.AddProject(projectInfo);

var miscFile = "class Foo {}";
var miscFileLoader = TextLoader.From(TextAndVersion.Create(SourceText.From(miscFile), VersionStamp.Create()));
SharedOmniSharpTestHost.Workspace.TryAddMiscellaneousDocument("dummy.cs", miscFileLoader, LanguageNames.CSharp);

const string input = @"
[assembly: System.Runtime.CompilerServices.InternalsVisibleTo(""$$";

var completions = await FindCompletionsAsync("dummy.cs", input, SharedOmniSharpTestHost);
Assert.Single(completions.Items);
Expand Down