提交 d5d152d8 编写于 作者: G Gen Lu

Support case mismatch in VB

上级 177cd446
......@@ -18,6 +18,8 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.Completion.Complet
MyBase.New(workspaceFixture)
End Sub
Private Property IsExpandedCompletion As Boolean = True
Private Property ShowImportCompletionItemsOptionValue As Boolean = True
' -1 would disable timebox, whereas 0 means always timeout.
......@@ -26,7 +28,8 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.Completion.Complet
Protected Overrides Sub SetWorkspaceOptions(workspace As TestWorkspace)
workspace.Options = workspace.Options _
.WithChangedOption(CompletionOptions.ShowItemsFromUnimportedNamespaces, LanguageNames.VisualBasic, ShowImportCompletionItemsOptionValue) _
.WithChangedOption(CompletionServiceOptions.TimeoutInMillisecondsForImportCompletion, TimeoutInMilliseconds)
.WithChangedOption(CompletionServiceOptions.TimeoutInMillisecondsForImportCompletion, TimeoutInMilliseconds) _
.WithChangedOption(CompletionServiceOptions.IsExpandedCompletion, IsExpandedCompletion)
End Sub
Protected Overrides Function GetExportProvider() As ExportProvider
......@@ -37,15 +40,42 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.Completion.Complet
Return New ExtensionMethodImportCompletionProvider()
End Function
<Fact, Trait(Traits.Feature, Traits.Features.Completion)>
Public Async Function TestExtensionAttribute() As Task
Public Enum ReferenceType
None
Project
Metadata
End Enum
Public Shared Function ReferenceTypeData() As IEnumerable(Of Object())
Return (New ReferenceType() {ReferenceType.None, ReferenceType.Project, ReferenceType.Metadata}).Select(Function(refType)
Return New Object() {refType}
End Function)
End Function
Private Shared Function GetMarkup(current As String, referenced As String, refType As ReferenceType, Optional currentLanguage As String = LanguageNames.VisualBasic, Optional referencedLanguage As String = LanguageNames.VisualBasic) As String
If refType = ReferenceType.None Then
Return CreateMarkupForSingleProject(current, referenced, currentLanguage)
ElseIf refType = ReferenceType.Project Then
Return GetMarkupWithReference(current, referenced, currentLanguage, referencedLanguage, True)
ElseIf refType = ReferenceType.Metadata Then
Return GetMarkupWithReference(current, referenced, currentLanguage, referencedLanguage, False)
Else
Return Nothing
End If
End Function
<InlineData(ReferenceType.None)>
<InlineData(ReferenceType.Project)>
<Theory, Trait(Traits.Feature, Traits.Features.Completion)>
Public Async Function TestExtensionAttribute(refType As ReferenceType) As Task
' attribute suffix isn't capitalized
Dim file1 = <Text><![CDATA[
Imports System
Imports System.Runtime.CompilerServices
Namespace Foo
Module ExtensionModule
Public Module ExtensionModule
<System.Runtime.CompilerServices.Extension()>
Public Sub ExtensionMethod1(aString As String)
......@@ -72,9 +102,14 @@ Namespace Foo
Console.WriteLine(aString)
End Sub
<extension()>
Public Sub ExtensionMethod6(aString As String)
Console.WriteLine(aString)
End Sub
Public Sub ExtensionMethod7(aString As String)
Console.WriteLine(aString)
End Sub
End Module
End Namespace]]></Text>.Value
......@@ -86,13 +121,91 @@ Public Class Bar
End Sub
End Class]]></Text>.Value
Dim markup = CreateMarkupForSingleProject(file2, file1, LanguageNames.VisualBasic)
Dim markup = GetMarkup(file2, file1, refType)
Await VerifyItemExistsAsync(markup, "ExtensionMethod1", glyph:=Glyph.ExtensionMethodPublic, inlineDescription:="Foo")
Await VerifyItemExistsAsync(markup, "ExtensionMethod2", glyph:=Glyph.ExtensionMethodPublic, inlineDescription:="Foo")
Await VerifyItemExistsAsync(markup, "ExtensionMethod3", glyph:=Glyph.ExtensionMethodPublic, inlineDescription:="Foo")
Await VerifyItemExistsAsync(markup, "ExtensionMethod4", glyph:=Glyph.ExtensionMethodPublic, inlineDescription:="Foo")
Await VerifyItemExistsAsync(markup, "ExtensionMethod5", glyph:=Glyph.ExtensionMethodPublic, inlineDescription:="Foo")
Await VerifyItemIsAbsentAsync(markup, "ExtensionMethod6", inlineDescription:="Foo")
Await VerifyItemExistsAsync(markup, "ExtensionMethod6", glyph:=Glyph.ExtensionMethodPublic, inlineDescription:="Foo")
Await VerifyItemIsAbsentAsync(markup, "ExtensionMethod7", inlineDescription:="Foo")
End Function
<InlineData(ReferenceType.None)>
<InlineData(ReferenceType.Project)>
<Theory, Trait(Traits.Feature, Traits.Features.Completion)>
Public Async Function TestCaseMismatchInTargetType(refType As ReferenceType) As Task
' attribute suffix isn't capitalized
Dim file1 = <Text><![CDATA[
Imports System
Imports System.Runtime.CompilerServices
Namespace Foo
Public Module ExtensionModule
<Extension>
Public Sub ExtensionMethod1(exp As exception)
End Sub
<Extension>
Public Sub ExtensionMethod2(exp As Exception)
Console.WriteLine(aString)
End Sub
End Module
End Namespace]]></Text>.Value
Dim file2 = <Text><![CDATA[
Imports System
Public Class Bar
Sub M(x as exception)
x.$$
End Sub
End Class]]></Text>.Value
Dim markup = GetMarkup(file2, file1, refType)
Await VerifyItemExistsAsync(markup, "ExtensionMethod1", glyph:=Glyph.ExtensionMethodPublic, inlineDescription:="Foo")
Await VerifyItemExistsAsync(markup, "ExtensionMethod2", glyph:=Glyph.ExtensionMethodPublic, inlineDescription:="Foo")
End Function
<InlineData(ReferenceType.None)>
<InlineData(ReferenceType.Project)>
<Theory, Trait(Traits.Feature, Traits.Features.Completion)>
Public Async Function TestCaseMismatchInNamespaceImport(refType As ReferenceType) As Task
' attribute suffix isn't capitalized
Dim file1 = <Text><![CDATA[
Imports System
Imports System.Runtime.CompilerServices
Namespace foo
Public Module ExtensionModule
<Extension>
Public Sub ExtensionMethod1(exp As exception)
End Sub
<Extension>
Public Sub ExtensionMethod2(exp As Exception)
Console.WriteLine(aString)
End Sub
End Module
End Namespace]]></Text>.Value
Dim file2 = <Text><![CDATA[
Imports System
Imports Foo
Public Class Bar
Sub M(x as exception)
x.$$
End Sub
End Class]]></Text>.Value
Dim markup = GetMarkup(file2, file1, refType)
Await VerifyItemIsAbsentAsync(markup, "ExtensionMethod1", inlineDescription:="Foo")
Await VerifyItemIsAbsentAsync(markup, "ExtensionMethod2", inlineDescription:="Foo")
End Function
End Class
End Namespace
......@@ -3,6 +3,7 @@
#nullable enable
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Composition;
using System.Threading;
......@@ -10,6 +11,7 @@
using Microsoft.CodeAnalysis.Completion.Providers.ImportCompletion;
using Microsoft.CodeAnalysis.FindSymbols;
using Microsoft.CodeAnalysis.Host.Mef;
using Microsoft.CodeAnalysis.LanguageServices;
using Microsoft.CodeAnalysis.PooledObjects;
using Microsoft.CodeAnalysis.Shared.Extensions;
using Roslyn.Utilities;
......@@ -21,6 +23,7 @@ internal static partial class ExtensionMethodImportCompletionService
private readonly struct CacheEntry
{
public Checksum Checksum { get; }
public string Language { get; }
public readonly MultiDictionary<string, DeclaredSymbolInfo> SimpleExtensionMethodInfo { get; }
......@@ -28,10 +31,12 @@ internal static partial class ExtensionMethodImportCompletionService
private CacheEntry(
Checksum checksum,
string language,
MultiDictionary<string, DeclaredSymbolInfo> simpleExtensionMethodInfo,
ImmutableArray<DeclaredSymbolInfo> complexExtensionMethodInfo)
{
Checksum = checksum;
Language = language;
SimpleExtensionMethodInfo = simpleExtensionMethodInfo;
ComplexExtensionMethodInfo = complexExtensionMethodInfo;
}
......@@ -39,15 +44,17 @@ internal static partial class ExtensionMethodImportCompletionService
public class Builder : IDisposable
{
private readonly Checksum _checksum;
private readonly string _language;
private readonly MultiDictionary<string, DeclaredSymbolInfo> _simpleItemBuilder;
private readonly ArrayBuilder<DeclaredSymbolInfo> _complexItemBuilder;
public Builder(Checksum checksum)
public Builder(Checksum checksum, string langauge, IEqualityComparer<string> comparer)
{
_checksum = checksum;
_language = langauge;
_simpleItemBuilder = new MultiDictionary<string, DeclaredSymbolInfo>();
_simpleItemBuilder = new MultiDictionary<string, DeclaredSymbolInfo>(comparer);
_complexItemBuilder = ArrayBuilder<DeclaredSymbolInfo>.GetInstance();
}
......@@ -55,6 +62,7 @@ public CacheEntry ToCacheEntry()
{
return new CacheEntry(
_checksum,
_language,
_simpleItemBuilder,
_complexItemBuilder.ToImmutable());
}
......@@ -107,9 +115,12 @@ public CacheServiceFactory()
// Cache miss, create all requested items.
if (!cacheService.ProjectItemsCache.TryGetValue(project.Id, out var cacheEntry) ||
cacheEntry.Checksum != checksum)
cacheEntry.Checksum != checksum ||
cacheEntry.Language != project.Language)
{
using var builder = new CacheEntry.Builder(checksum);
var syntaxFacts = project.LanguageServices.GetRequiredService<ISyntaxFactsService>();
using var builder = new CacheEntry.Builder(checksum, project.Language, syntaxFacts.StringComparer);
foreach (var document in project.Documents)
{
// Don't look for extension methods in generated code.
......
......@@ -70,6 +70,7 @@ internal static partial class ExtensionMethodImportCompletionService
counter.TotalTicks = Environment.TickCount - ticks;
counter.TotalExtensionMethodsProvided = serializableItems.Length;
counter.Report();
// TODO: remove this
Internal.Log.Logger.Log(Internal.Log.FunctionId.Completion_ExtensionMethodImportCompletionProvider_GetCompletionItemsAsync, Internal.Log.KeyValueLogMessage.Create(m =>
......@@ -133,7 +134,6 @@ internal static partial class ExtensionMethodImportCompletionService
counter.NoFilter = matchedMethods == null;
// Don't show unimported extension methods if the index isn't ready.
// TODO: hide expander button
if (matchedMethods == null)
{
// We use a very simple approach to build the cache in the background:
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册