提交 bb4202a4 编写于 作者: C CyrusNajmabadi 提交者: GitHub

Merge pull request #18725 from CyrusNajmabadi/navToNoSymbol

Don't require a symbol at all for NavigateTo.
......@@ -47,7 +47,7 @@ public async Task FindClass()
{
SetupVerifiableGlyph(StandardGlyphGroup.GlyphGroupClass, StandardGlyphItem.GlyphItemPrivate);
var item = (await _aggregator.GetItemsAsync("Foo")).Single(x => x.Kind != "Method");
VerifyNavigateToResultItem(item, "Foo", MatchKind.Exact, NavigateToItemKind.Class);
VerifyNavigateToResultItem(item, "Foo", "[|Foo|]", MatchKind.Exact, NavigateToItemKind.Class);
});
}
......@@ -67,7 +67,7 @@ internal class DogBed
{
SetupVerifiableGlyph(StandardGlyphGroup.GlyphGroupClass, StandardGlyphItem.GlyphItemFriend);
var item = (await _aggregator.GetItemsAsync("DogBed")).Single(x => x.Kind != "Method");
VerifyNavigateToResultItem(item, "DogBed", MatchKind.Exact, NavigateToItemKind.Class);
VerifyNavigateToResultItem(item, "DogBed", "[|DogBed|]", MatchKind.Exact, NavigateToItemKind.Class);
});
}
......@@ -90,7 +90,7 @@ public void Method()
{
SetupVerifiableGlyph(StandardGlyphGroup.GlyphGroupMethod, StandardGlyphItem.GlyphItemPublic);
var item = (await _aggregator.GetItemsAsync("Method")).Single();
VerifyNavigateToResultItem(item, "Method", MatchKind.Exact, NavigateToItemKind.Method, "Method()", $"{FeaturesResources.type_space}Foo.Bar.DogBed");
VerifyNavigateToResultItem(item, "Method", "[|Method|]()", MatchKind.Exact, NavigateToItemKind.Method, $"{FeaturesResources.type_space}Foo.Bar.DogBed");
});
}
......@@ -106,7 +106,7 @@ class Foo<T> where T : IEnumerable
{
SetupVerifiableGlyph(StandardGlyphGroup.GlyphGroupClass, StandardGlyphItem.GlyphItemPrivate);
var item = (await _aggregator.GetItemsAsync("Foo")).Single(x => x.Kind != "Method");
VerifyNavigateToResultItem(item, "Foo", MatchKind.Exact, NavigateToItemKind.Class, displayName: "Foo<T>");
VerifyNavigateToResultItem(item, "Foo", "[|Foo|]<T>", MatchKind.Exact, NavigateToItemKind.Class);
});
}
......@@ -125,7 +125,7 @@ class Foo<U>
{
SetupVerifiableGlyph(StandardGlyphGroup.GlyphGroupMethod, StandardGlyphItem.GlyphItemPublic);
var item = (await _aggregator.GetItemsAsync("Bar")).Single();
VerifyNavigateToResultItem(item, "Bar", MatchKind.Exact, NavigateToItemKind.Method, "Bar<T>(T)", $"{FeaturesResources.type_space}Foo<U>");
VerifyNavigateToResultItem(item, "Bar", "[|Bar|]<T>(T)", MatchKind.Exact, NavigateToItemKind.Method, $"{FeaturesResources.type_space}Foo<U>");
});
}
......@@ -178,7 +178,7 @@ class Foo
{
SetupVerifiableGlyph(StandardGlyphGroup.GlyphGroupClass, StandardGlyphItem.GlyphItemFriend);
var item = (await _aggregator.GetItemsAsync("Foo")).Single(x => x.Kind != "Method");
VerifyNavigateToResultItem(item, "Foo", MatchKind.Exact, NavigateToItemKind.Class);
VerifyNavigateToResultItem(item, "Foo", "[|Foo|]", MatchKind.Exact, NavigateToItemKind.Class);
});
}
......@@ -192,7 +192,7 @@ public async Task FindStruct()
{
SetupVerifiableGlyph(StandardGlyphGroup.GlyphGroupStruct, StandardGlyphItem.GlyphItemPrivate);
var item = (await _aggregator.GetItemsAsync("B")).Single(x => x.Kind != "Method");
VerifyNavigateToResultItem(item, "Bar", MatchKind.Prefix, NavigateToItemKind.Structure);
VerifyNavigateToResultItem(item, "Bar", "[|B|]ar", MatchKind.Prefix, NavigateToItemKind.Structure);
});
}
......@@ -209,7 +209,7 @@ public async Task FindEnum()
{
SetupVerifiableGlyph(StandardGlyphGroup.GlyphGroupEnum, StandardGlyphItem.GlyphItemPrivate);
var item = (await _aggregator.GetItemsAsync("Colors")).Single(x => x.Kind != "Method");
VerifyNavigateToResultItem(item, "Colors", MatchKind.Exact, NavigateToItemKind.Enum);
VerifyNavigateToResultItem(item, "Colors", "[|Colors|]", MatchKind.Exact, NavigateToItemKind.Enum);
});
}
......@@ -226,7 +226,7 @@ public async Task FindEnumMember()
{
SetupVerifiableGlyph(StandardGlyphGroup.GlyphGroupEnumMember, StandardGlyphItem.GlyphItemPublic);
var item = (await _aggregator.GetItemsAsync("R")).Single();
VerifyNavigateToResultItem(item, "Red", MatchKind.Prefix, NavigateToItemKind.EnumItem);
VerifyNavigateToResultItem(item, "Red", "[|R|]ed", MatchKind.Prefix, NavigateToItemKind.EnumItem);
});
}
......@@ -241,7 +241,7 @@ public async Task FindConstField()
{
SetupVerifiableGlyph(StandardGlyphGroup.GlyphGroupConstant, StandardGlyphItem.GlyphItemPrivate);
var item = (await _aggregator.GetItemsAsync("ba")).Single();
VerifyNavigateToResultItem(item, "bar", MatchKind.Prefix, NavigateToItemKind.Constant);
VerifyNavigateToResultItem(item, "bar", "[|ba|]r", MatchKind.Prefix, NavigateToItemKind.Constant);
});
}
......@@ -256,7 +256,7 @@ public async Task FindVerbatimIdentifier()
{
SetupVerifiableGlyph(StandardGlyphGroup.GlyphGroupField, StandardGlyphItem.GlyphItemPrivate);
var item = (await _aggregator.GetItemsAsync("string")).Single();
VerifyNavigateToResultItem(item, "string", MatchKind.Exact, NavigateToItemKind.Field, displayName: "@string", additionalInfo: $"{FeaturesResources.type_space}Foo");
VerifyNavigateToResultItem(item, "string", "[|string|]", MatchKind.Exact, NavigateToItemKind.Field, additionalInfo: $"{FeaturesResources.type_space}Foo");
});
}
......@@ -268,7 +268,7 @@ public async Task FindIndexer()
{
SetupVerifiableGlyph(StandardGlyphGroup.GlyphGroupProperty, StandardGlyphItem.GlyphItemPublic);
var item = (await _aggregator.GetItemsAsync("this")).Single();
VerifyNavigateToResultItem(item, "this[]", MatchKind.Exact, NavigateToItemKind.Property, displayName: "this[int]", additionalInfo: $"{FeaturesResources.type_space}Foo");
VerifyNavigateToResultItem(item, "this", "[|this|][int]", MatchKind.Exact, NavigateToItemKind.Property, additionalInfo: $"{FeaturesResources.type_space}Foo");
});
}
......@@ -280,7 +280,7 @@ public async Task FindEvent()
{
SetupVerifiableGlyph(StandardGlyphGroup.GlyphGroupEvent, StandardGlyphItem.GlyphItemPublic);
var item = (await _aggregator.GetItemsAsync("CEH")).Single();
VerifyNavigateToResultItem(item, "ChangedEventHandler", MatchKind.Regular, NavigateToItemKind.Event, additionalInfo: $"{FeaturesResources.type_space}Foo");
VerifyNavigateToResultItem(item, "ChangedEventHandler", "[|C|]hanged[|E|]vent[|H|]andler", MatchKind.Regular, NavigateToItemKind.Event, additionalInfo: $"{FeaturesResources.type_space}Foo");
});
}
......@@ -295,7 +295,7 @@ public async Task FindAutoProperty()
{
SetupVerifiableGlyph(StandardGlyphGroup.GlyphGroupProperty, StandardGlyphItem.GlyphItemPrivate);
var item = (await _aggregator.GetItemsAsync("B")).Single();
VerifyNavigateToResultItem(item, "Bar", MatchKind.Prefix, NavigateToItemKind.Property, additionalInfo: $"{FeaturesResources.type_space}Foo");
VerifyNavigateToResultItem(item, "Bar", "[|B|]ar", MatchKind.Prefix, NavigateToItemKind.Property, additionalInfo: $"{FeaturesResources.type_space}Foo");
});
}
......@@ -310,7 +310,7 @@ public async Task FindMethod()
{
SetupVerifiableGlyph(StandardGlyphGroup.GlyphGroupMethod, StandardGlyphItem.GlyphItemPrivate);
var item = (await _aggregator.GetItemsAsync("DS")).Single();
VerifyNavigateToResultItem(item, "DoSomething", MatchKind.Regular, NavigateToItemKind.Method, "DoSomething()", $"{FeaturesResources.type_space}Foo");
VerifyNavigateToResultItem(item, "DoSomething", "[|D|]o[|S|]omething()", MatchKind.Regular, NavigateToItemKind.Method, $"{FeaturesResources.type_space}Foo");
});
}
......@@ -327,7 +327,7 @@ void DoSomething(int a, string b)
{
SetupVerifiableGlyph(StandardGlyphGroup.GlyphGroupMethod, StandardGlyphItem.GlyphItemPrivate);
var item = (await _aggregator.GetItemsAsync("DS")).Single();
VerifyNavigateToResultItem(item, "DoSomething", MatchKind.Regular, NavigateToItemKind.Method, "DoSomething(int, string)", $"{FeaturesResources.type_space}Foo");
VerifyNavigateToResultItem(item, "DoSomething", "[|D|]o[|S|]omething(int, string)", MatchKind.Regular, NavigateToItemKind.Method, $"{FeaturesResources.type_space}Foo");
});
}
......@@ -344,7 +344,7 @@ public Foo()
{
SetupVerifiableGlyph(StandardGlyphGroup.GlyphGroupMethod, StandardGlyphItem.GlyphItemPublic);
var item = (await _aggregator.GetItemsAsync("Foo")).Single(t => t.Kind == NavigateToItemKind.Method);
VerifyNavigateToResultItem(item, "Foo", MatchKind.Exact, NavigateToItemKind.Method, "Foo()", $"{FeaturesResources.type_space}Foo");
VerifyNavigateToResultItem(item, "Foo", "[|Foo|]()", MatchKind.Exact, NavigateToItemKind.Method, $"{FeaturesResources.type_space}Foo");
});
}
......@@ -361,7 +361,7 @@ public Foo(int i)
{
SetupVerifiableGlyph(StandardGlyphGroup.GlyphGroupMethod, StandardGlyphItem.GlyphItemPublic);
var item = (await _aggregator.GetItemsAsync("Foo")).Single(t => t.Kind == NavigateToItemKind.Method);
VerifyNavigateToResultItem(item, "Foo", MatchKind.Exact, NavigateToItemKind.Method, "Foo(int)", $"{FeaturesResources.type_space}Foo");
VerifyNavigateToResultItem(item, "Foo", "[|Foo|](int)", MatchKind.Exact, NavigateToItemKind.Method, $"{FeaturesResources.type_space}Foo");
});
}
......@@ -378,7 +378,7 @@ static Foo()
{
SetupVerifiableGlyph(StandardGlyphGroup.GlyphGroupMethod, StandardGlyphItem.GlyphItemPrivate);
var item = (await _aggregator.GetItemsAsync("Foo")).Single(t => t.Kind == NavigateToItemKind.Method && t.Name != ".ctor");
VerifyNavigateToResultItem(item, "Foo", MatchKind.Exact, NavigateToItemKind.Method, "static Foo()", $"{FeaturesResources.type_space}Foo");
VerifyNavigateToResultItem(item, "Foo", "[|Foo|].static Foo()", MatchKind.Exact, NavigateToItemKind.Method, $"{FeaturesResources.type_space}Foo");
});
}
......@@ -407,7 +407,7 @@ public async Task FindPartialMethodDefinitionOnly()
{
SetupVerifiableGlyph(StandardGlyphGroup.GlyphGroupMethod, StandardGlyphItem.GlyphItemPrivate);
var item = (await _aggregator.GetItemsAsync("Bar")).Single();
VerifyNavigateToResultItem(item, "Bar", MatchKind.Exact, NavigateToItemKind.Method, "Bar()", $"{FeaturesResources.type_space}Foo");
VerifyNavigateToResultItem(item, "Bar", "[|Bar|]()", MatchKind.Exact, NavigateToItemKind.Method, $"{FeaturesResources.type_space}Foo");
});
}
......@@ -453,7 +453,7 @@ public async Task FindInterface()
{
SetupVerifiableGlyph(StandardGlyphGroup.GlyphGroupInterface, StandardGlyphItem.GlyphItemPublic);
var item = (await _aggregator.GetItemsAsync("IF")).Single();
VerifyNavigateToResultItem(item, "IFoo", MatchKind.Prefix, NavigateToItemKind.Interface, displayName: "IFoo");
VerifyNavigateToResultItem(item, "IFoo", "[|IF|]oo", MatchKind.Prefix, NavigateToItemKind.Interface);
});
}
......@@ -468,7 +468,7 @@ public async Task FindDelegateInNamespace()
{
SetupVerifiableGlyph(StandardGlyphGroup.GlyphGroupDelegate, StandardGlyphItem.GlyphItemFriend);
var item = (await _aggregator.GetItemsAsync("DoStuff")).Single(x => x.Kind != "Method");
VerifyNavigateToResultItem(item, "DoStuff", MatchKind.Exact, NavigateToItemKind.Delegate, displayName: "DoStuff");
VerifyNavigateToResultItem(item, "DoStuff", "[|DoStuff|]", MatchKind.Exact, NavigateToItemKind.Delegate);
});
}
......@@ -485,7 +485,7 @@ class Foo
{
SetupVerifiableGlyph(StandardGlyphGroup.GlyphGroupField, StandardGlyphItem.GlyphItemPrivate);
var item = (await _aggregator.GetItemsAsync("sqr")).Single();
VerifyNavigateToResultItem(item, "sqr", MatchKind.Exact, NavigateToItemKind.Field, "sqr", $"{FeaturesResources.type_space}Foo");
VerifyNavigateToResultItem(item, "sqr", "[|sqr|]", MatchKind.Exact, NavigateToItemKind.Field, $"{FeaturesResources.type_space}Foo");
});
}
......@@ -640,7 +640,7 @@ public async Task TermSplittingTest5()
{
SetupVerifiableGlyph(StandardGlyphGroup.GlyphGroupField, StandardGlyphItem.GlyphItemPrivate);
var item = (await _aggregator.GetItemsAsync("G_K_W")).Single();
VerifyNavigateToResultItem(item, "get_key_word", MatchKind.Regular, NavigateToItemKind.Field);
VerifyNavigateToResultItem(item, "get_key_word", "[|g|]et[|_k|]ey[|_w|]ord", MatchKind.Regular, NavigateToItemKind.Field);
});
}
......
......@@ -6,7 +6,9 @@
using System.Threading;
using Microsoft.CodeAnalysis.NavigateTo;
using Microsoft.CodeAnalysis.Navigation;
using Microsoft.CodeAnalysis.Text.Shared.Extensions;
using Microsoft.VisualStudio.Language.NavigateTo.Interfaces;
using Microsoft.VisualStudio.Text;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.Editor.Implementation.NavigateTo
......@@ -130,5 +132,7 @@ public void PreviewItem()
previewService.PreviewItem(this);
}
public IReadOnlyList<Span> GetNameMatchRuns(string searchValue)
=> SearchResult.NameMatchSpans.NullToEmpty().SelectAsArray(ts => ts.ToSpan());
}
}
\ No newline at end of file
......@@ -53,7 +53,10 @@ public static StandardGlyphGroup GetStandardGlyphGroup(this Glyph glyph)
case Glyph.EnumInternal:
return StandardGlyphGroup.GlyphGroupEnum;
case Glyph.EnumMember:
case Glyph.EnumMemberPublic:
case Glyph.EnumMemberProtected:
case Glyph.EnumMemberPrivate:
case Glyph.EnumMemberInternal:
return StandardGlyphGroup.GlyphGroupEnumMember;
case Glyph.Error:
......@@ -272,7 +275,10 @@ public static ImageMoniker GetImageMoniker(this Glyph glyph)
case Glyph.EnumInternal:
return KnownMonikers.EnumerationInternal;
case Glyph.EnumMember:
case Glyph.EnumMemberPublic:
case Glyph.EnumMemberProtected:
case Glyph.EnumMemberPrivate:
case Glyph.EnumMemberInternal:
return KnownMonikers.EnumerationItemPublic;
case Glyph.Error:
......@@ -472,14 +478,14 @@ public static Glyph GetGlyph(this ImmutableArray<string> tags)
switch (GetAccessibility(tags))
{
case Accessibility.Protected:
return Glyph.EnumMember;
return Glyph.EnumMemberProtected;
case Accessibility.Private:
return Glyph.EnumMember;
return Glyph.EnumMemberPrivate;
case Accessibility.Internal:
return Glyph.EnumMember;
return Glyph.EnumMemberInternal;
case Accessibility.Public:
default:
return Glyph.EnumMember;
return Glyph.EnumMemberPublic;
}
case WellKnownTags.Error:
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.Drawing;
using Microsoft.CodeAnalysis.Editor.Implementation.NavigateTo;
using Microsoft.CodeAnalysis.Editor.Shared.Extensions;
using Microsoft.CodeAnalysis.NavigateTo;
using Microsoft.CodeAnalysis.Text.Shared.Extensions;
using Microsoft.VisualStudio.Imaging.Interop;
using Microsoft.VisualStudio.Language.NavigateTo.Interfaces;
using Microsoft.VisualStudio.Text;
......@@ -38,9 +36,6 @@ public Dev15NavigateToItemDisplay(INavigateToSearchResult searchResult)
public IReadOnlyList<Span> GetAdditionalInformationMatchRuns(string searchValue)
=> SpecializedCollections.EmptyReadOnlyList<Span>();
public IReadOnlyList<Span> GetNameMatchRuns(string searchValue)
=> SearchResult.NameMatchSpans.NullToEmpty().SelectAsArray(ts => ts.ToSpan());
}
}
}
\ No newline at end of file
......@@ -60,7 +60,7 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.NavigationBar
</Project>
</Workspace>,
Item("E", Glyph.EnumInternal), False,
Item("A", Glyph.EnumMember), False)
Item("A", Glyph.EnumMemberPublic), False)
End Function
<Fact, Trait(Traits.Feature, Traits.Features.NavigationBar), WorkItem(545114, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545114")>
......@@ -167,9 +167,9 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.NavigationBar
</Project>
</Workspace>,
Item("Foo", Glyph.EnumInternal, children:={
Item("A", Glyph.EnumMember),
Item("B", Glyph.EnumMember),
Item("C", Glyph.EnumMember)}))
Item("A", Glyph.EnumMemberPublic),
Item("B", Glyph.EnumMemberPublic),
Item("C", Glyph.EnumMemberPublic)}))
End Function
<Fact, Trait(Traits.Feature, Traits.Features.NavigationBar), WorkItem(545220, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545220")>
......
......@@ -806,9 +806,9 @@ End Enum
</Project>
</Workspace>,
Item("MyEnum", Glyph.EnumInternal, children:={
Item("A", Glyph.EnumMember),
Item("B", Glyph.EnumMember),
Item("C", Glyph.EnumMember)},
Item("A", Glyph.EnumMemberPublic),
Item("B", Glyph.EnumMemberPublic),
Item("C", Glyph.EnumMemberPublic)},
bolded:=True))
End Function
......
......@@ -2,6 +2,7 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Media;
......@@ -9,14 +10,17 @@
using System.Xml.Linq;
using Microsoft.CodeAnalysis.Editor.Extensibility.Composition;
using Microsoft.CodeAnalysis.Editor.Implementation.NavigateTo;
using Microsoft.CodeAnalysis.Editor.Shared.Extensions;
using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces;
using Microsoft.CodeAnalysis.NavigateTo;
using Microsoft.CodeAnalysis.Shared.TestHooks;
using Microsoft.CodeAnalysis.Text;
using Microsoft.VisualStudio.Composition;
using Microsoft.VisualStudio.Language.Intellisense;
using Microsoft.VisualStudio.Language.NavigateTo.Interfaces;
using Moq;
using Roslyn.Test.EditorUtilities.NavigateTo;
using Roslyn.Test.Utilities;
using Xunit;
namespace Microsoft.CodeAnalysis.Editor.UnitTests.NavigateTo
......@@ -79,7 +83,8 @@ private void InitializeWorkspace(TestWorkspace workspace)
_aggregator = new NavigateToTestAggregator(_provider);
}
protected void VerifyNavigateToResultItems(List<NavigateToItem> expecteditems, IEnumerable<NavigateToItem> items)
protected void VerifyNavigateToResultItems(
List<NavigateToItem> expecteditems, IEnumerable<NavigateToItem> items)
{
expecteditems = expecteditems.OrderBy(i => i.Name).ToList();
items = items.OrderBy(i => i.Name).ToList();
......@@ -102,8 +107,10 @@ protected void VerifyNavigateToResultItems(List<NavigateToItem> expecteditems, I
}
}
protected void VerifyNavigateToResultItem(NavigateToItem result, string name, MatchKind matchKind, string navigateToItemKind,
string displayName = null, string additionalInfo = null)
protected void VerifyNavigateToResultItem(
NavigateToItem result, string name, string displayMarkup,
MatchKind matchKind, string navigateToItemKind,
string additionalInfo = null)
{
// Verify symbol information
Assert.Equal(name, result.Name);
......@@ -111,10 +118,15 @@ protected void VerifyNavigateToResultItems(List<NavigateToItem> expecteditems, I
Assert.Equal(this.Language, result.Language);
Assert.Equal(navigateToItemKind, result.Kind);
// Verify display
var itemDisplay = result.DisplayFactory.CreateItemDisplay(result);
MarkupTestFile.GetSpans(displayMarkup, out displayMarkup,
out ImmutableArray<TextSpan> expectedDisplayNameSpans);
Assert.Equal(displayName ?? name, itemDisplay.Name);
var itemDisplay = (AbstractNavigateToItemDisplay)result.DisplayFactory.CreateItemDisplay(result);
Assert.Equal(displayMarkup, itemDisplay.Name);
Assert.Equal<TextSpan>(
expectedDisplayNameSpans,
itemDisplay.GetNameMatchRuns("").Select(s => s.ToTextSpan()).ToImmutableArray());
if (additionalInfo != null)
{
......
......@@ -34,7 +34,10 @@ internal enum Glyph
EnumPrivate,
EnumInternal,
EnumMember,
EnumMemberPublic,
EnumMemberProtected,
EnumMemberPrivate,
EnumMemberInternal,
Error,
StatusInformation,
......
......@@ -32,7 +32,10 @@ public static ImmutableArray<string> GetTags(Glyph glyph)
case Glyph.EnumProtected: return WellKnownTagArrays.EnumProtected;
case Glyph.EnumPrivate: return WellKnownTagArrays.EnumPrivate;
case Glyph.EnumInternal: return WellKnownTagArrays.EnumInternal;
case Glyph.EnumMember: return WellKnownTagArrays.EnumMember;
case Glyph.EnumMemberPublic: return WellKnownTagArrays.EnumMemberPublic;
case Glyph.EnumMemberProtected: return WellKnownTagArrays.EnumMemberProtected;
case Glyph.EnumMemberPrivate: return WellKnownTagArrays.EnumMemberPrivate;
case Glyph.EnumMemberInternal: return WellKnownTagArrays.EnumMemberInternal;
case Glyph.Error: return WellKnownTagArrays.Error;
case Glyph.EventPublic: return WellKnownTagArrays.EventPublic;
case Glyph.EventProtected: return WellKnownTagArrays.EventProtected;
......
......@@ -51,7 +51,7 @@ internal abstract partial class AbstractNavigateToSearchService
{
cancellationToken.ThrowIfCancellationRequested();
var patternMatches = patternMatcher.GetMatches(
GetSearchName(declaredSymbolInfo),
declaredSymbolInfo.Name,
declaredSymbolInfo.FullyQualifiedContainerName,
includeMatchSpans: true);
......@@ -66,18 +66,6 @@ internal abstract partial class AbstractNavigateToSearchService
}
}
private static string GetSearchName(DeclaredSymbolInfo declaredSymbolInfo)
{
if (declaredSymbolInfo.Kind == DeclaredSymbolInfoKind.Indexer && declaredSymbolInfo.Name == WellKnownMemberNames.Indexer)
{
return "this";
}
else
{
return declaredSymbolInfo.Name;
}
}
private static INavigateToSearchResult ConvertResult(
bool containsDots, DeclaredSymbolInfo declaredSymbolInfo,
Document document, PatternMatches matches)
......@@ -92,7 +80,8 @@ private static string GetSearchName(DeclaredSymbolInfo declaredSymbolInfo)
return new SearchResult(
document, declaredSymbolInfo, kind, matchKind,
isCaseSensitive, navigableItem, matches.CandidateMatches.SelectMany(m => m.MatchedSpans).ToImmutableArray());
isCaseSensitive, navigableItem,
matches.CandidateMatches.SelectMany(m => m.MatchedSpans).ToImmutableArray());
}
private static string GetItemKind(DeclaredSymbolInfo declaredSymbolInfo)
......@@ -116,6 +105,7 @@ private static string GetItemKind(DeclaredSymbolInfo declaredSymbolInfo)
case DeclaredSymbolInfoKind.Interface:
return NavigateToItemKind.Interface;
case DeclaredSymbolInfoKind.Constructor:
case DeclaredSymbolInfoKind.ExtensionMethod:
case DeclaredSymbolInfoKind.Method:
return NavigateToItemKind.Method;
case DeclaredSymbolInfoKind.Module:
......
......@@ -6,7 +6,6 @@
using System.IO;
using Microsoft.CodeAnalysis.FindSymbols;
using Microsoft.CodeAnalysis.Navigation;
using Microsoft.CodeAnalysis.Shared.Extensions;
using Microsoft.CodeAnalysis.Text;
namespace Microsoft.CodeAnalysis.NavigateTo
......@@ -17,7 +16,7 @@ private class SearchResult : INavigateToSearchResult
{
public string AdditionalInformation => _lazyAdditionalInfo.Value;
public string Name => _declaredSymbolInfo.Name;
public string Summary => _lazySummary.Value;
public string Summary { get; }
public string Kind { get; }
public NavigateToMatchKind MatchKind { get; }
......@@ -29,7 +28,6 @@ private class SearchResult : INavigateToSearchResult
private readonly Document _document;
private readonly DeclaredSymbolInfo _declaredSymbolInfo;
private readonly Lazy<string> _lazyAdditionalInfo;
private readonly Lazy<string> _lazySummary;
public SearchResult(
Document document, DeclaredSymbolInfo declaredSymbolInfo, string kind,
......@@ -48,7 +46,6 @@ private class SearchResult : INavigateToSearchResult
var declaredNavigableItem = navigableItem as NavigableItemFactory.DeclaredSymbolNavigableItem;
Debug.Assert(declaredNavigableItem != null);
_lazySummary = new Lazy<string>(() => declaredNavigableItem.SymbolOpt?.GetDocumentationComment()?.SummaryText);
_lazyAdditionalInfo = new Lazy<string>(() =>
{
switch (declaredSymbolInfo.Kind)
......
......@@ -2,12 +2,9 @@
using System;
using System.Collections.Immutable;
using System.Threading;
using Microsoft.CodeAnalysis.ErrorReporting;
using Microsoft.CodeAnalysis.FindSymbols;
using Microsoft.CodeAnalysis.Shared.Extensions;
using Microsoft.CodeAnalysis.Tags;
using Microsoft.CodeAnalysis.Text;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.Navigation
{
......@@ -15,64 +12,84 @@ internal partial class NavigableItemFactory
{
internal class DeclaredSymbolNavigableItem : INavigableItem
{
public ImmutableArray<TaggedText> DisplayTaggedParts => _lazyDisplayTaggedParts.Value;
private readonly DeclaredSymbolInfo _declaredSymbolInfo;
public Document Document { get; }
public Glyph Glyph => this.SymbolOpt?.GetGlyph() ?? Glyph.Error;
public ImmutableArray<TaggedText> DisplayTaggedParts
=> ImmutableArray.Create(new TaggedText(
TextTags.Text, _declaredSymbolInfo.Name + _declaredSymbolInfo.NameSuffix));
public Glyph Glyph => GetGlyph(_declaredSymbolInfo.Kind, _declaredSymbolInfo.Accessibility);
public TextSpan SourceSpan => _declaredSymbolInfo.Span;
public ISymbol SymbolOpt => _lazySymbolOpt.Value;
public ImmutableArray<INavigableItem> ChildItems => ImmutableArray<INavigableItem>.Empty;
public ImmutableArray<INavigableItem> ChildItems => ImmutableArray<INavigableItem>.Empty;
public bool DisplayFileLocation => false;
private readonly DeclaredSymbolInfo _declaredSymbolInfo;
private readonly Lazy<ImmutableArray<TaggedText>> _lazyDisplayTaggedParts;
private readonly Lazy<ISymbol> _lazySymbolOpt;
/// <summary>
/// DeclaredSymbolInfos always come from some actual declaration in source. So they're
/// never implicitly declared.
/// </summary>
public bool IsImplicitlyDeclared => false;
public DeclaredSymbolNavigableItem(Document document, DeclaredSymbolInfo declaredSymbolInfo)
public DeclaredSymbolNavigableItem(
Document document, DeclaredSymbolInfo declaredSymbolInfo)
{
Document = document;
_declaredSymbolInfo = declaredSymbolInfo;
}
_lazySymbolOpt = new Lazy<ISymbol>(TryFindSymbol);
_lazyDisplayTaggedParts = new Lazy<ImmutableArray<TaggedText>>(() =>
private static Glyph GetPublicGlyph(DeclaredSymbolInfoKind kind)
{
switch (kind)
{
try
{
if (this.SymbolOpt == null)
{
return default(ImmutableArray<TaggedText>);
}
return GetSymbolDisplayTaggedParts(Document.Project, this.SymbolOpt);
}
catch (Exception e) when (FatalError.Report(e))
{
throw ExceptionUtilities.Unreachable;
}
});
case DeclaredSymbolInfoKind.Class: return Glyph.ClassPublic;
case DeclaredSymbolInfoKind.Constant: return Glyph.ConstantPublic;
case DeclaredSymbolInfoKind.Constructor: return Glyph.MethodPublic;
case DeclaredSymbolInfoKind.Delegate: return Glyph.DelegatePublic;
case DeclaredSymbolInfoKind.Enum: return Glyph.EnumPublic;
case DeclaredSymbolInfoKind.EnumMember: return Glyph.EnumMemberPublic;
case DeclaredSymbolInfoKind.Event: return Glyph.EventPublic;
case DeclaredSymbolInfoKind.ExtensionMethod: return Glyph.ExtensionMethodPublic;
case DeclaredSymbolInfoKind.Field: return Glyph.FieldPublic;
case DeclaredSymbolInfoKind.Indexer: return Glyph.PropertyPublic;
case DeclaredSymbolInfoKind.Interface: return Glyph.InterfacePublic;
case DeclaredSymbolInfoKind.Method: return Glyph.MethodPublic;
case DeclaredSymbolInfoKind.Module: return Glyph.ModulePublic;
case DeclaredSymbolInfoKind.Property: return Glyph.PropertyPublic;
case DeclaredSymbolInfoKind.Struct: return Glyph.StructurePublic;
default: return Glyph.ClassPublic;
}
}
private ISymbol TryFindSymbol()
private static Glyph GetGlyph(DeclaredSymbolInfoKind kind, Accessibility accessibility)
{
// Here, we will use partial semantics. We are going to use this symbol to get a glyph, display string,
// and potentially documentation comments. The first two should work fine even if we don't have full
// references, and the latter will probably be fine. (It wouldn't be if you have a partial type
// and we didn't get all the trees parsed yet to know that. In other words, an edge case we don't care about.)
// Glyphs are stored in this order:
// ClassPublic,
// ClassProtected,
// ClassPrivate,
// ClassInternal,
var rawGlyph = GetPublicGlyph(kind);
// Cancellation isn't supported when computing the various properties that depend on the symbol, hence
// CancellationToken.None.
var semanticModel = Document.GetPartialSemanticModelAsync(CancellationToken.None).GetAwaiter().GetResult();
switch (accessibility)
{
case Accessibility.Private:
rawGlyph += (Glyph.ClassPrivate - Glyph.ClassPublic);
break;
case Accessibility.Internal:
rawGlyph += (Glyph.ClassInternal - Glyph.ClassPublic);
break;
case Accessibility.Protected:
case Accessibility.ProtectedOrInternal:
case Accessibility.ProtectedAndInternal:
rawGlyph += (Glyph.ClassProtected - Glyph.ClassPublic);
break;
}
return _declaredSymbolInfo.TryResolve(semanticModel, CancellationToken.None);
return rawGlyph;
}
}
}
}
}
\ No newline at end of file
......@@ -5,8 +5,6 @@
using System.Linq;
using System.Threading;
using Microsoft.CodeAnalysis.FindSymbols;
using Microsoft.CodeAnalysis.GeneratedCodeRecognition;
using Microsoft.CodeAnalysis.LanguageServices;
using Microsoft.CodeAnalysis.Shared.Extensions;
using Roslyn.Utilities;
......@@ -79,51 +77,5 @@ private static IEnumerable<Location> GetPreferredSourceLocations(ISymbol symbol)
? navigableItems.Where(n => !n.Document.IsGeneratedCode(cancellationToken))
: navigableItems.Where(n => n.Document.IsGeneratedCode(cancellationToken));
}
public static ImmutableArray<TaggedText> GetSymbolDisplayTaggedParts(Project project, ISymbol symbol)
{
var symbolDisplayService = project.LanguageServices.GetRequiredService<ISymbolDisplayService>();
return symbolDisplayService.ToDisplayParts(symbol, GetSymbolDisplayFormat(symbol)).ToTaggedText();
}
private static SymbolDisplayFormat GetSymbolDisplayFormat(ISymbol symbol)
{
switch (symbol.Kind)
{
case SymbolKind.NamedType:
return s_shortFormatWithModifiers;
case SymbolKind.Method:
return symbol.IsStaticConstructor() ? s_shortFormatWithModifiers : s_shortFormat;
default:
return s_shortFormat;
}
}
private static readonly SymbolDisplayFormat s_shortFormat =
new SymbolDisplayFormat(
globalNamespaceStyle: SymbolDisplayGlobalNamespaceStyle.OmittedAsContaining,
typeQualificationStyle: SymbolDisplayTypeQualificationStyle.NameOnly,
propertyStyle: SymbolDisplayPropertyStyle.NameOnly,
genericsOptions:
SymbolDisplayGenericsOptions.IncludeTypeParameters |
SymbolDisplayGenericsOptions.IncludeVariance,
memberOptions:
SymbolDisplayMemberOptions.IncludeExplicitInterface |
SymbolDisplayMemberOptions.IncludeParameters,
parameterOptions:
SymbolDisplayParameterOptions.IncludeExtensionThis |
SymbolDisplayParameterOptions.IncludeParamsRefOut |
SymbolDisplayParameterOptions.IncludeType,
miscellaneousOptions:
SymbolDisplayMiscellaneousOptions.EscapeKeywordIdentifiers |
SymbolDisplayMiscellaneousOptions.UseSpecialTypes);
private static readonly SymbolDisplayFormat s_shortFormatWithModifiers =
s_shortFormat.WithMemberOptions(
SymbolDisplayMemberOptions.IncludeModifiers |
SymbolDisplayMemberOptions.IncludeExplicitInterface |
SymbolDisplayMemberOptions.IncludeParameters);
}
}
\ No newline at end of file
......@@ -37,7 +37,7 @@ public static Glyph GetGlyph(this ISymbol symbol)
var containingType = symbol.ContainingType;
if (containingType != null && containingType.TypeKind == TypeKind.Enum)
{
return Glyph.EnumMember;
return Glyph.EnumMemberPublic;
}
publicIcon = ((IFieldSymbol)symbol).IsConst ? Glyph.ConstantPublic : Glyph.FieldPublic;
......
......@@ -776,99 +776,129 @@ public bool TryGetDeclaredSymbolInfo(SyntaxNode node, out DeclaredSymbolInfo dec
{
case SyntaxKind.ClassDeclaration:
var classDecl = (ClassDeclarationSyntax)node;
declaredSymbolInfo = new DeclaredSymbolInfo(classDecl.Identifier.ValueText,
declaredSymbolInfo = new DeclaredSymbolInfo(
classDecl.Identifier.ValueText,
GetTypeParameterSuffix(classDecl.TypeParameterList),
GetContainerDisplayName(node.Parent),
GetFullyQualifiedContainerName(node.Parent),
DeclaredSymbolInfoKind.Class, classDecl.Identifier.Span,
DeclaredSymbolInfoKind.Class,
GetAccessibility(classDecl, classDecl.Modifiers),
classDecl.Identifier.Span,
GetInheritanceNames(classDecl.BaseList));
return true;
case SyntaxKind.ConstructorDeclaration:
var ctorDecl = (ConstructorDeclarationSyntax)node;
declaredSymbolInfo = new DeclaredSymbolInfo(
ctorDecl.Identifier.ValueText,
GetConstructorSuffix(ctorDecl),
GetContainerDisplayName(node.Parent),
GetFullyQualifiedContainerName(node.Parent),
DeclaredSymbolInfoKind.Constructor,
GetAccessibility(ctorDecl, ctorDecl.Modifiers),
ctorDecl.Identifier.Span,
inheritanceNames: ImmutableArray<string>.Empty,
parameterCount: (ushort)(ctorDecl.ParameterList?.Parameters.Count ?? 0));
parameterCount: ctorDecl.ParameterList?.Parameters.Count ?? 0);
return true;
case SyntaxKind.DelegateDeclaration:
var delegateDecl = (DelegateDeclarationSyntax)node;
declaredSymbolInfo = new DeclaredSymbolInfo(delegateDecl.Identifier.ValueText,
declaredSymbolInfo = new DeclaredSymbolInfo(
delegateDecl.Identifier.ValueText,
GetTypeParameterSuffix(delegateDecl.TypeParameterList),
GetContainerDisplayName(node.Parent),
GetFullyQualifiedContainerName(node.Parent),
DeclaredSymbolInfoKind.Delegate, delegateDecl.Identifier.Span,
DeclaredSymbolInfoKind.Delegate,
GetAccessibility(delegateDecl, delegateDecl.Modifiers),
delegateDecl.Identifier.Span,
inheritanceNames: ImmutableArray<string>.Empty);
return true;
case SyntaxKind.EnumDeclaration:
var enumDecl = (EnumDeclarationSyntax)node;
declaredSymbolInfo = new DeclaredSymbolInfo(enumDecl.Identifier.ValueText,
declaredSymbolInfo = new DeclaredSymbolInfo(
enumDecl.Identifier.ValueText, null,
GetContainerDisplayName(node.Parent),
GetFullyQualifiedContainerName(node.Parent),
DeclaredSymbolInfoKind.Enum, enumDecl.Identifier.Span,
DeclaredSymbolInfoKind.Enum,
GetAccessibility(enumDecl, enumDecl.Modifiers),
enumDecl.Identifier.Span,
inheritanceNames: ImmutableArray<string>.Empty);
return true;
case SyntaxKind.EnumMemberDeclaration:
var enumMember = (EnumMemberDeclarationSyntax)node;
declaredSymbolInfo = new DeclaredSymbolInfo(enumMember.Identifier.ValueText,
declaredSymbolInfo = new DeclaredSymbolInfo(
enumMember.Identifier.ValueText, null,
GetContainerDisplayName(node.Parent),
GetFullyQualifiedContainerName(node.Parent),
DeclaredSymbolInfoKind.EnumMember, enumMember.Identifier.Span,
DeclaredSymbolInfoKind.EnumMember,
Accessibility.Public,
enumMember.Identifier.Span,
inheritanceNames: ImmutableArray<string>.Empty);
return true;
case SyntaxKind.EventDeclaration:
var eventDecl = (EventDeclarationSyntax)node;
declaredSymbolInfo = new DeclaredSymbolInfo(
ExpandExplicitInterfaceName(eventDecl.Identifier.ValueText, eventDecl.ExplicitInterfaceSpecifier),
eventDecl.Identifier.ValueText, null,
GetContainerDisplayName(node.Parent),
GetFullyQualifiedContainerName(node.Parent),
DeclaredSymbolInfoKind.Event, eventDecl.Identifier.Span,
DeclaredSymbolInfoKind.Event,
GetAccessibility(eventDecl, eventDecl.Modifiers),
eventDecl.Identifier.Span,
inheritanceNames: ImmutableArray<string>.Empty);
return true;
case SyntaxKind.IndexerDeclaration:
var indexerDecl = (IndexerDeclarationSyntax)node;
declaredSymbolInfo = new DeclaredSymbolInfo(WellKnownMemberNames.Indexer,
declaredSymbolInfo = new DeclaredSymbolInfo(
"this", GetIndexerSuffix(indexerDecl),
GetContainerDisplayName(node.Parent),
GetFullyQualifiedContainerName(node.Parent),
DeclaredSymbolInfoKind.Indexer, indexerDecl.ThisKeyword.Span,
DeclaredSymbolInfoKind.Indexer,
GetAccessibility(indexerDecl, indexerDecl.Modifiers),
indexerDecl.ThisKeyword.Span,
inheritanceNames: ImmutableArray<string>.Empty);
return true;
case SyntaxKind.InterfaceDeclaration:
var interfaceDecl = (InterfaceDeclarationSyntax)node;
declaredSymbolInfo = new DeclaredSymbolInfo(interfaceDecl.Identifier.ValueText,
declaredSymbolInfo = new DeclaredSymbolInfo(
interfaceDecl.Identifier.ValueText, GetTypeParameterSuffix(interfaceDecl.TypeParameterList),
GetContainerDisplayName(node.Parent),
GetFullyQualifiedContainerName(node.Parent),
DeclaredSymbolInfoKind.Interface, interfaceDecl.Identifier.Span,
DeclaredSymbolInfoKind.Interface,
GetAccessibility(interfaceDecl, interfaceDecl.Modifiers),
interfaceDecl.Identifier.Span,
GetInheritanceNames(interfaceDecl.BaseList));
return true;
case SyntaxKind.MethodDeclaration:
var method = (MethodDeclarationSyntax)node;
declaredSymbolInfo = new DeclaredSymbolInfo(
ExpandExplicitInterfaceName(method.Identifier.ValueText, method.ExplicitInterfaceSpecifier),
method.Identifier.ValueText, GetMethodSuffix(method),
GetContainerDisplayName(node.Parent),
GetFullyQualifiedContainerName(node.Parent),
DeclaredSymbolInfoKind.Method,
IsExtensionMethod(method) ? DeclaredSymbolInfoKind.ExtensionMethod : DeclaredSymbolInfoKind.Method,
GetAccessibility(method, method.Modifiers),
method.Identifier.Span,
inheritanceNames: ImmutableArray<string>.Empty,
parameterCount: (ushort)(method.ParameterList?.Parameters.Count ?? 0),
typeParameterCount: (ushort)(method.TypeParameterList?.Parameters.Count ?? 0));
parameterCount: method.ParameterList?.Parameters.Count ?? 0,
typeParameterCount: method.TypeParameterList?.Parameters.Count ?? 0);
return true;
case SyntaxKind.PropertyDeclaration:
var property = (PropertyDeclarationSyntax)node;
declaredSymbolInfo = new DeclaredSymbolInfo(
ExpandExplicitInterfaceName(property.Identifier.ValueText, property.ExplicitInterfaceSpecifier),
property.Identifier.ValueText, null,
GetContainerDisplayName(node.Parent),
GetFullyQualifiedContainerName(node.Parent),
DeclaredSymbolInfoKind.Property, property.Identifier.Span,
DeclaredSymbolInfoKind.Property,
GetAccessibility(property, property.Modifiers),
property.Identifier.Span,
inheritanceNames: ImmutableArray<string>.Empty);
return true;
case SyntaxKind.StructDeclaration:
var structDecl = (StructDeclarationSyntax)node;
declaredSymbolInfo = new DeclaredSymbolInfo(structDecl.Identifier.ValueText,
declaredSymbolInfo = new DeclaredSymbolInfo(
structDecl.Identifier.ValueText, GetTypeParameterSuffix(structDecl.TypeParameterList),
GetContainerDisplayName(node.Parent),
GetFullyQualifiedContainerName(node.Parent),
DeclaredSymbolInfoKind.Struct, structDecl.Identifier.Span,
DeclaredSymbolInfoKind.Struct,
GetAccessibility(structDecl, structDecl.Modifiers),
structDecl.Identifier.Span,
GetInheritanceNames(structDecl.BaseList));
return true;
case SyntaxKind.VariableDeclarator:
......@@ -885,10 +915,12 @@ public bool TryGetDeclaredSymbolInfo(SyntaxNode node, out DeclaredSymbolInfo dec
: DeclaredSymbolInfoKind.Field;
declaredSymbolInfo = new DeclaredSymbolInfo(
variableDeclarator.Identifier.ValueText,
variableDeclarator.Identifier.ValueText, null,
GetContainerDisplayName(fieldDeclaration.Parent),
GetFullyQualifiedContainerName(fieldDeclaration.Parent),
kind, variableDeclarator.Identifier.Span,
kind,
GetAccessibility(fieldDeclaration, fieldDeclaration.Modifiers),
variableDeclarator.Identifier.Span,
inheritanceNames: ImmutableArray<string>.Empty);
return true;
}
......@@ -900,6 +932,144 @@ public bool TryGetDeclaredSymbolInfo(SyntaxNode node, out DeclaredSymbolInfo dec
return false;
}
private string GetConstructorSuffix(ConstructorDeclarationSyntax constructor)
=> constructor.Modifiers.Any(SyntaxKind.StaticKeyword)
? ".static " + constructor.Identifier + "()"
: GetSuffix('(', ')', constructor.ParameterList.Parameters);
private string GetMethodSuffix(MethodDeclarationSyntax method)
=> GetTypeParameterSuffix(method.TypeParameterList) +
GetSuffix('(', ')', method.ParameterList.Parameters);
private string GetIndexerSuffix(IndexerDeclarationSyntax indexer)
=> GetSuffix('[', ']', indexer.ParameterList.Parameters);
private string GetTypeParameterSuffix(TypeParameterListSyntax typeParameterList)
{
if (typeParameterList == null)
{
return null;
}
var pooledBuilder = PooledStringBuilder.GetInstance();
var builder = pooledBuilder.Builder;
builder.Append('<');
var first = true;
foreach (var parameter in typeParameterList.Parameters)
{
if (!first)
{
builder.Append(", ");
}
builder.Append(parameter.Identifier.Text);
}
builder.Append('>');
return pooledBuilder.ToStringAndFree();
}
/// <summary>
/// Builds up the suffix to show for something with parameters in navigate-to.
/// While it would be nice to just use the compiler SymbolDisplay API for this,
/// it would be too expensive as it requires going back to Symbols (which requires
/// creating compilations, etc.) in a perf sensitive area.
///
/// So, instead, we just build a reasonable suffix using the pure syntax that a
/// user provided. That means that if they wrote "Method(System.Int32 i)" we'll
/// show that as "Method(System.Int32)" not "Method(int)". Given that this is
/// actually what the user wrote, and it saves us from ever having to go back to
/// symbols/compilations, this is well worth it, even if it does mean we have to
/// create our own 'symbol display' logic here.
/// </summary>
private string GetSuffix(
char openBrace, char closeBrace, SeparatedSyntaxList<ParameterSyntax> parameters)
{
var pooledBuilder = PooledStringBuilder.GetInstance();
var builder = pooledBuilder.Builder;
builder.Append(openBrace);
AppendParameters(parameters, builder);
builder.Append(closeBrace);
return pooledBuilder.ToStringAndFree();
}
private void AppendParameters(SeparatedSyntaxList<ParameterSyntax> parameters, StringBuilder builder)
{
var first = true;
foreach (var parameter in parameters)
{
if (!first)
{
builder.Append(", ");
}
foreach (var modifier in parameter.Modifiers)
{
builder.Append(modifier.Text);
builder.Append(' ');
}
AppendTokens(parameter.Type, builder);
first = false;
}
}
private bool IsExtensionMethod(MethodDeclarationSyntax method)
=> method.ParameterList.Parameters.Count > 0 &&
method.ParameterList.Parameters[0].Modifiers.Any(SyntaxKind.ThisKeyword);
private Accessibility GetAccessibility(SyntaxNode node, SyntaxTokenList modifiers)
{
var sawInternal = false;
foreach (var modifier in modifiers)
{
switch (modifier.Kind())
{
case SyntaxKind.PublicKeyword: return Accessibility.Public;
case SyntaxKind.PrivateKeyword: return Accessibility.Private;
case SyntaxKind.ProtectedKeyword: return Accessibility.Protected;
case SyntaxKind.InternalKeyword:
sawInternal = true;
continue;
}
}
if (sawInternal)
{
return Accessibility.Internal;
}
// No accessibility modifiers:
switch (node.Parent.Kind())
{
case SyntaxKind.ClassDeclaration:
case SyntaxKind.StructDeclaration:
// Anything without modifiers is private if it's in a class/struct declaration.
return Accessibility.Private;
case SyntaxKind.InterfaceDeclaration:
// Anything without modifiers is public if it's in an interface declaration.
return Accessibility.Public;
case SyntaxKind.CompilationUnit:
// Things are private by default in script
if (((CSharpParseOptions)node.SyntaxTree.Options).Kind == SourceCodeKind.Script)
{
return Accessibility.Private;
}
return Accessibility.Internal;
default:
// Otherwise it's internal
return Accessibility.Internal;
}
}
private ImmutableArray<string> GetInheritanceNames(BaseListSyntax baseList)
{
if (baseList == null)
......@@ -1035,13 +1205,6 @@ private string GetTypeName(TypeSyntax type)
private static string GetSimpleTypeName(SimpleNameSyntax name)
=> name.Identifier.ValueText;
private static string ExpandExplicitInterfaceName(string identifier, ExplicitInterfaceSpecifierSyntax explicitInterfaceSpecifier)
{
return explicitInterfaceSpecifier == null
? identifier
: $"{explicitInterfaceSpecifier.Name.GetNameToken().ValueText}.{identifier}";
}
private string GetContainerDisplayName(SyntaxNode node)
{
return GetDisplayName(node, DisplayNameOptions.IncludeTypeParameters);
......
......@@ -2,6 +2,7 @@
using System;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.ErrorReporting;
......@@ -19,60 +20,115 @@ internal enum DeclaredSymbolInfoKind : byte
Enum,
EnumMember,
Event,
ExtensionMethod,
Field,
Indexer,
Interface,
Method,
Module,
Property,
Struct
Struct,
}
internal struct DeclaredSymbolInfo
{
/// <summary>
/// The name to pattern match against, and to show in a final presentation layer.
/// </summary>
public string Name { get; }
/// <summary>
/// An optional suffix to be shown in a presentation layer appended to <see cref="Name"/>.
/// Can be null.
/// </summary>
public string NameSuffix { get; }
/// <summary>
/// Container of the symbol that can be shown in a final presentation layer.
/// For example, the container of a type "KeyValuePair" might be
/// "System.Collections.Generic.Dictionary&lt;TKey, TValue&gt;". This can
/// then be shown with something like "type System.Collections.Generic.Dictionary&lt;TKey, TValue&gt;"
/// to indicate where the symbol is located.
/// </summary>
public string ContainerDisplayName { get; }
/// <summary>
/// Dotted container name of the symbol, used for pattern matching. For example
/// The fully qualified container of a type "KeyValuePair" would be
/// "System.Collections.Generic.Dictionary" (note the lack of type parameters).
/// This way someone can search for "D.KVP" and have the "D" part of the pattern
/// match against this. This should not be shown in a presentation layer.
/// </summary>
public string FullyQualifiedContainerName { get; }
public DeclaredSymbolInfoKind Kind { get; }
public TextSpan Span { get; }
public ushort ParameterCount { get; }
public ushort TypeParameterCount { get; }
// Store the kind, accessibility, parameter-count, and type-parameter-count
// in a single int. Each gets 4 bits which is ample and gives us more space
// for flags in the future.
private readonly uint _flags;
private const uint Lower4BitMask = 0b1111;
public DeclaredSymbolInfoKind Kind => GetKind(_flags);
public Accessibility Accessibility => GetAccessibility(_flags);
public byte ParameterCount => GetParameterCount(_flags);
public byte TypeParameterCount => GetTypeParameterCount(_flags);
/// <summary>
/// The names directly referenced in source that this type inherits from.
/// </summary>
public ImmutableArray<string> InheritanceNames { get; }
public ImmutableArray<string> InheritanceNames { get; }
public DeclaredSymbolInfo(
string name,
string nameSuffix,
string containerDisplayName,
string fullyQualifiedContainerName,
DeclaredSymbolInfoKind kind,
Accessibility accessibility,
TextSpan span,
ImmutableArray<string> inheritanceNames,
ushort parameterCount = 0, ushort typeParameterCount = 0)
int parameterCount = 0, int typeParameterCount = 0)
: this()
{
Name = name;
NameSuffix = nameSuffix;
ContainerDisplayName = containerDisplayName;
FullyQualifiedContainerName = fullyQualifiedContainerName;
Kind = kind;
Span = span;
ParameterCount = parameterCount;
TypeParameterCount = typeParameterCount;
InheritanceNames = inheritanceNames;
const uint MaxFlagValue = 0b1111;
Contract.ThrowIfTrue((uint)accessibility > MaxFlagValue);
Contract.ThrowIfTrue((uint)kind > MaxFlagValue);
parameterCount = Math.Min(parameterCount, (byte)MaxFlagValue);
typeParameterCount = Math.Min(typeParameterCount, (byte)MaxFlagValue);
_flags = (uint)kind | ((uint)accessibility << 4) | ((uint)parameterCount << 8) | ((uint)typeParameterCount << 12);
}
private static DeclaredSymbolInfoKind GetKind(uint flags)
=> (DeclaredSymbolInfoKind)(flags & Lower4BitMask);
private static Accessibility GetAccessibility(uint flags)
=> (Accessibility)((flags >> 4) & Lower4BitMask);
private static byte GetParameterCount(uint flags)
=> (byte)((flags >> 8) & Lower4BitMask);
private static byte GetTypeParameterCount(uint flags)
=> (byte)((flags >> 12) & Lower4BitMask);
internal void WriteTo(ObjectWriter writer)
{
writer.WriteString(Name);
writer.WriteString(NameSuffix);
writer.WriteString(ContainerDisplayName);
writer.WriteString(FullyQualifiedContainerName);
writer.WriteByte((byte)Kind);
writer.WriteUInt32(_flags);
writer.WriteInt32(Span.Start);
writer.WriteInt32(Span.Length);
writer.WriteUInt16(ParameterCount);
writer.WriteUInt16(TypeParameterCount);
writer.WriteInt32(InheritanceNames.Length);
foreach (var name in InheritanceNames)
......@@ -84,24 +140,32 @@ internal void WriteTo(ObjectWriter writer)
internal static DeclaredSymbolInfo ReadFrom_ThrowsOnFailure(ObjectReader reader)
{
var name = reader.ReadString();
var immediateContainer = reader.ReadString();
var entireContainer = reader.ReadString();
var kind = (DeclaredSymbolInfoKind)reader.ReadByte();
var nameSuffix = reader.ReadString();
var containerDisplayName = reader.ReadString();
var fullyQualifiedContainerName = reader.ReadString();
var flags = reader.ReadUInt32();
var spanStart = reader.ReadInt32();
var spanLength = reader.ReadInt32();
var parameterCount = reader.ReadUInt16();
var typeParameterCount = reader.ReadUInt16();
var inheritanceNamesLength = reader.ReadInt32();
var builder = ImmutableArray.CreateBuilder<string>(inheritanceNamesLength);
var builder = ArrayBuilder<string>.GetInstance(inheritanceNamesLength);
for (var i = 0; i < inheritanceNamesLength; i++)
{
builder.Add(reader.ReadString());
}
var span = new TextSpan(spanStart, spanLength);
return new DeclaredSymbolInfo(
name, immediateContainer, entireContainer, kind, new TextSpan(spanStart, spanLength),
builder.MoveToImmutable(), parameterCount, typeParameterCount);
name: name,
nameSuffix: nameSuffix,
containerDisplayName: containerDisplayName,
fullyQualifiedContainerName: fullyQualifiedContainerName,
kind: GetKind(flags),
accessibility: GetAccessibility(flags),
span: span,
inheritanceNames: builder.ToImmutableAndFree(),
parameterCount: GetParameterCount(flags),
typeParameterCount: GetTypeParameterCount(flags));
}
public async Task<ISymbol> TryResolveAsync(Document document, CancellationToken cancellationToken)
......
......@@ -15,7 +15,7 @@ namespace Microsoft.CodeAnalysis.FindSymbols
internal sealed partial class SyntaxTreeIndex : IObjectWritable
{
private const string PersistenceName = "<TreeInfoPersistence>";
private const string SerializationFormat = "3";
private const string SerializationFormat = "6";
/// <summary>
/// in memory cache will hold onto any info related to opened documents in primary branch or all documents in forked branch
......
......@@ -10,6 +10,7 @@
using Microsoft.CodeAnalysis.Shared.Utilities;
using Microsoft.CodeAnalysis.Text;
using Roslyn.Utilities;
using System.Text;
namespace Microsoft.CodeAnalysis.LanguageServices
{
......@@ -391,5 +392,20 @@ public string GetBannerText(SyntaxNode documentationCommentTriviaSyntax, Cancell
=> DocumentationCommentService.GetBannerText(documentationCommentTriviaSyntax, cancellationToken);
protected abstract IDocumentationCommentService DocumentationCommentService { get; }
protected static void AppendTokens(SyntaxNode node, StringBuilder builder)
{
foreach (var child in node.ChildNodesAndTokens())
{
if (child.IsToken)
{
builder.Append(child.AsToken().Text);
}
else
{
AppendTokens(child.AsNode(), builder);
}
}
}
}
}
\ No newline at end of file
......@@ -70,10 +70,13 @@ internal static class WellKnownTagArrays
internal static readonly ImmutableArray<string> DelegatePrivate = ImmutableArray.Create(WellKnownTags.Delegate, WellKnownTags.Private);
internal static readonly ImmutableArray<string> DelegateInternal = ImmutableArray.Create(WellKnownTags.Delegate, WellKnownTags.Internal);
internal static readonly ImmutableArray<string> EnumPublic = ImmutableArray.Create(WellKnownTags.Enum, WellKnownTags.Public);
internal static readonly ImmutableArray<string> EnumProtected = ImmutableArray.Create(WellKnownTags.Enum, WellKnownTags.Public);
internal static readonly ImmutableArray<string> EnumProtected = ImmutableArray.Create(WellKnownTags.Enum, WellKnownTags.Protected);
internal static readonly ImmutableArray<string> EnumPrivate = ImmutableArray.Create(WellKnownTags.Enum, WellKnownTags.Private);
internal static readonly ImmutableArray<string> EnumInternal = ImmutableArray.Create(WellKnownTags.Enum, WellKnownTags.Internal);
internal static readonly ImmutableArray<string> EnumMember = ImmutableArray.Create(WellKnownTags.EnumMember);
internal static readonly ImmutableArray<string> EnumMemberPublic = ImmutableArray.Create(WellKnownTags.EnumMember, WellKnownTags.Public);
internal static readonly ImmutableArray<string> EnumMemberProtected = ImmutableArray.Create(WellKnownTags.EnumMember, WellKnownTags.Protected);
internal static readonly ImmutableArray<string> EnumMemberPrivate = ImmutableArray.Create(WellKnownTags.EnumMember, WellKnownTags.Private);
internal static readonly ImmutableArray<string> EnumMemberInternal = ImmutableArray.Create(WellKnownTags.EnumMember, WellKnownTags.Internal);
internal static readonly ImmutableArray<string> EventPublic = ImmutableArray.Create(WellKnownTags.Event, WellKnownTags.Public);
internal static readonly ImmutableArray<string> EventProtected = ImmutableArray.Create(WellKnownTags.Event, WellKnownTags.Protected);
internal static readonly ImmutableArray<string> EventPrivate = ImmutableArray.Create(WellKnownTags.Event, WellKnownTags.Private);
......
......@@ -845,9 +845,12 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Dim classDecl = CType(node, ClassBlockSyntax)
declaredSymbolInfo = New DeclaredSymbolInfo(
classDecl.ClassStatement.Identifier.ValueText,
GetTypeParameterSuffix(classDecl.ClassStatement.TypeParameterList),
GetContainerDisplayName(node.Parent),
GetFullyQualifiedContainerName(node.Parent),
DeclaredSymbolInfoKind.Class, classDecl.ClassStatement.Identifier.Span,
DeclaredSymbolInfoKind.Class,
GetAccessibility(classDecl, classDecl.ClassStatement.Modifiers),
classDecl.ClassStatement.Identifier.Span,
GetInheritanceNames(classDecl))
Return True
Case SyntaxKind.ConstructorBlock
......@@ -856,12 +859,14 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
If typeBlock IsNot Nothing Then
declaredSymbolInfo = New DeclaredSymbolInfo(
typeBlock.BlockStatement.Identifier.ValueText,
GetConstructorSuffix(constructor),
GetContainerDisplayName(node.Parent),
GetFullyQualifiedContainerName(node.Parent),
DeclaredSymbolInfoKind.Constructor,
GetAccessibility(constructor, constructor.SubNewStatement.Modifiers),
constructor.SubNewStatement.NewKeyword.Span,
ImmutableArray(Of String).Empty,
parameterCount:=CType(If(constructor.SubNewStatement.ParameterList?.Parameters.Count, 0), UShort))
parameterCount:=If(constructor.SubNewStatement.ParameterList?.Parameters.Count, 0))
Return True
End If
......@@ -869,58 +874,73 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Dim delegateDecl = CType(node, DelegateStatementSyntax)
declaredSymbolInfo = New DeclaredSymbolInfo(
delegateDecl.Identifier.ValueText,
GetTypeParameterSuffix(delegateDecl.TypeParameterList),
GetContainerDisplayName(node.Parent),
GetFullyQualifiedContainerName(node.Parent),
DeclaredSymbolInfoKind.Delegate, delegateDecl.Identifier.Span,
DeclaredSymbolInfoKind.Delegate,
GetAccessibility(delegateDecl, delegateDecl.Modifiers),
delegateDecl.Identifier.Span,
ImmutableArray(Of String).Empty)
Return True
Case SyntaxKind.EnumBlock
Dim enumDecl = CType(node, EnumBlockSyntax)
declaredSymbolInfo = New DeclaredSymbolInfo(
enumDecl.EnumStatement.Identifier.ValueText,
enumDecl.EnumStatement.Identifier.ValueText, Nothing,
GetContainerDisplayName(node.Parent),
GetFullyQualifiedContainerName(node.Parent),
DeclaredSymbolInfoKind.Enum, enumDecl.EnumStatement.Identifier.Span,
DeclaredSymbolInfoKind.Enum,
GetAccessibility(enumDecl, enumDecl.EnumStatement.Modifiers),
enumDecl.EnumStatement.Identifier.Span,
ImmutableArray(Of String).Empty)
Return True
Case SyntaxKind.EnumMemberDeclaration
Dim enumMember = CType(node, EnumMemberDeclarationSyntax)
declaredSymbolInfo = New DeclaredSymbolInfo(
enumMember.Identifier.ValueText,
enumMember.Identifier.ValueText, Nothing,
GetContainerDisplayName(node.Parent),
GetFullyQualifiedContainerName(node.Parent),
DeclaredSymbolInfoKind.EnumMember, enumMember.Identifier.Span,
DeclaredSymbolInfoKind.EnumMember,
Accessibility.Public,
enumMember.Identifier.Span,
ImmutableArray(Of String).Empty)
Return True
Case SyntaxKind.EventStatement
Dim eventDecl = CType(node, EventStatementSyntax)
Dim eventParent = If(TypeOf node.Parent Is EventBlockSyntax, node.Parent.Parent, node.Parent)
Dim statementOrBlock = If(TypeOf node.Parent Is EventBlockSyntax, node.Parent, node)
Dim eventParent = statementOrBlock.Parent
declaredSymbolInfo = New DeclaredSymbolInfo(
eventDecl.Identifier.ValueText,
eventDecl.Identifier.ValueText, Nothing,
GetContainerDisplayName(eventParent),
GetFullyQualifiedContainerName(eventParent),
DeclaredSymbolInfoKind.Event, eventDecl.Identifier.Span,
DeclaredSymbolInfoKind.Event,
GetAccessibility(statementOrBlock, eventDecl.Modifiers),
eventDecl.Identifier.Span,
ImmutableArray(Of String).Empty)
Return True
Case SyntaxKind.FunctionBlock, SyntaxKind.SubBlock
Dim funcDecl = CType(node, MethodBlockSyntax)
declaredSymbolInfo = New DeclaredSymbolInfo(
funcDecl.SubOrFunctionStatement.Identifier.ValueText,
GetMethodSuffix(funcDecl),
GetContainerDisplayName(node.Parent),
GetFullyQualifiedContainerName(node.Parent),
DeclaredSymbolInfoKind.Method,
GetAccessibility(node, funcDecl.SubOrFunctionStatement.Modifiers),
funcDecl.SubOrFunctionStatement.Identifier.Span,
ImmutableArray(Of String).Empty,
parameterCount:=CType(If(funcDecl.SubOrFunctionStatement.ParameterList?.Parameters.Count, 0), UShort),
typeParameterCount:=CType(If(funcDecl.SubOrFunctionStatement.TypeParameterList?.Parameters.Count, 0), UShort))
parameterCount:=If(funcDecl.SubOrFunctionStatement.ParameterList?.Parameters.Count, 0),
typeParameterCount:=If(funcDecl.SubOrFunctionStatement.TypeParameterList?.Parameters.Count, 0))
Return True
Case SyntaxKind.InterfaceBlock
Dim interfaceDecl = CType(node, InterfaceBlockSyntax)
declaredSymbolInfo = New DeclaredSymbolInfo(
interfaceDecl.InterfaceStatement.Identifier.ValueText,
GetTypeParameterSuffix(interfaceDecl.InterfaceStatement.TypeParameterList),
GetContainerDisplayName(node.Parent),
GetFullyQualifiedContainerName(node.Parent),
DeclaredSymbolInfoKind.Interface, interfaceDecl.InterfaceStatement.Identifier.Span,
DeclaredSymbolInfoKind.Interface,
GetAccessibility(interfaceDecl, interfaceDecl.InterfaceStatement.Modifiers),
interfaceDecl.InterfaceStatement.Identifier.Span,
GetInheritanceNames(interfaceDecl))
Return True
Case SyntaxKind.ModifiedIdentifier
......@@ -932,10 +952,11 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
DeclaredSymbolInfoKind.Constant,
DeclaredSymbolInfoKind.Field)
declaredSymbolInfo = New DeclaredSymbolInfo(
modifiedIdentifier.Identifier.ValueText,
modifiedIdentifier.Identifier.ValueText, Nothing,
GetContainerDisplayName(fieldDecl.Parent),
GetFullyQualifiedContainerName(fieldDecl.Parent),
kind, modifiedIdentifier.Identifier.Span,
kind, GetAccessibility(fieldDecl, fieldDecl.Modifiers),
modifiedIdentifier.Identifier.Span,
ImmutableArray(Of String).Empty)
Return True
End If
......@@ -943,28 +964,37 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Dim moduleDecl = CType(node, ModuleBlockSyntax)
declaredSymbolInfo = New DeclaredSymbolInfo(
moduleDecl.ModuleStatement.Identifier.ValueText,
GetTypeParameterSuffix(moduleDecl.ModuleStatement.TypeParameterList),
GetContainerDisplayName(node.Parent),
GetFullyQualifiedContainerName(node.Parent),
DeclaredSymbolInfoKind.Module, moduleDecl.ModuleStatement.Identifier.Span,
DeclaredSymbolInfoKind.Module,
GetAccessibility(moduleDecl, moduleDecl.ModuleStatement.Modifiers),
moduleDecl.ModuleStatement.Identifier.Span,
GetInheritanceNames(moduleDecl))
Return True
Case SyntaxKind.PropertyStatement
Dim propertyDecl = CType(node, PropertyStatementSyntax)
Dim propertyParent = If(TypeOf node.Parent Is PropertyBlockSyntax, node.Parent.Parent, node.Parent)
Dim statementOrBlock = If(TypeOf node.Parent Is PropertyBlockSyntax, node.Parent, node)
Dim propertyParent = statementOrBlock.Parent
declaredSymbolInfo = New DeclaredSymbolInfo(
propertyDecl.Identifier.ValueText,
propertyDecl.Identifier.ValueText, GetPropertySuffix(propertyDecl),
GetContainerDisplayName(propertyParent),
GetFullyQualifiedContainerName(propertyParent),
DeclaredSymbolInfoKind.Property, propertyDecl.Identifier.Span,
DeclaredSymbolInfoKind.Property,
GetAccessibility(statementOrBlock, propertyDecl.Modifiers),
propertyDecl.Identifier.Span,
ImmutableArray(Of String).Empty)
Return True
Case SyntaxKind.StructureBlock
Dim structDecl = CType(node, StructureBlockSyntax)
declaredSymbolInfo = New DeclaredSymbolInfo(
structDecl.StructureStatement.Identifier.ValueText,
GetTypeParameterSuffix(structDecl.StructureStatement.TypeParameterList),
GetContainerDisplayName(node.Parent),
GetFullyQualifiedContainerName(node.Parent),
DeclaredSymbolInfoKind.Struct, structDecl.StructureStatement.Identifier.Span,
DeclaredSymbolInfoKind.Struct,
GetAccessibility(structDecl, structDecl.StructureStatement.Modifiers),
structDecl.StructureStatement.Identifier.Span,
GetInheritanceNames(structDecl))
Return True
End Select
......@@ -973,6 +1003,145 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Return False
End Function
Private Function GetMethodSuffix(method As MethodBlockSyntax) As String
Return GetTypeParameterSuffix(method.SubOrFunctionStatement.TypeParameterList) &
GetSuffix(method.SubOrFunctionStatement.ParameterList)
End Function
Private Function GetConstructorSuffix(method As ConstructorBlockSyntax) As String
Return ".New" & GetSuffix(method.SubNewStatement.ParameterList)
End Function
Private Function GetPropertySuffix([property] As PropertyStatementSyntax) As String
If [property].ParameterList Is Nothing Then
Return Nothing
End If
Return GetSuffix([property].ParameterList)
End Function
Private Function GetTypeParameterSuffix(typeParameterList As TypeParameterListSyntax) As String
If typeParameterList Is Nothing Then
Return Nothing
End If
Dim pooledBuilder = PooledStringBuilder.GetInstance()
Dim builder = pooledBuilder.Builder
builder.Append("(Of ")
Dim First = True
For Each parameter In typeParameterList.Parameters
If Not First Then
builder.Append(", ")
End If
builder.Append(parameter.Identifier.Text)
First = False
Next
builder.Append(")"c)
Return pooledBuilder.ToStringAndFree()
End Function
''' <summary>
''' Builds up the suffix to show for something with parameters in navigate-to.
''' While it would be nice to just use the compiler SymbolDisplay API for this,
''' it would be too expensive as it requires going back to Symbols (which requires
''' creating compilations, etc.) in a perf sensitive area.
'''
''' So, instead, we just build a reasonable suffix using the pure syntax that a
''' user provided. That means that if they wrote "Method(System.Int32 i)" we'll
''' show that as "Method(System.Int32)" Not "Method(Integer)". Given that this Is
''' actually what the user wrote, And it saves us from ever having to go back to
''' symbols/compilations, this Is well worth it, even if it does mean we have to
''' create our own 'symbol display' logic here.
''' </summary>
Private Function GetSuffix(parameterList As ParameterListSyntax) As String
If parameterList Is Nothing OrElse parameterList.Parameters.Count = 0 Then
Return "()"
End If
Dim pooledBuilder = PooledStringBuilder.GetInstance()
Dim builder = pooledBuilder.Builder
builder.Append("("c)
If parameterList IsNot Nothing Then
AppendParameters(parameterList.Parameters, builder)
End If
builder.Append(")"c)
Return pooledBuilder.ToStringAndFree()
End Function
Private Sub AppendParameters(parameters As SeparatedSyntaxList(Of ParameterSyntax), builder As StringBuilder)
Dim First = True
For Each parameter In parameters
If Not First Then
builder.Append(", ")
End If
For Each modifier In parameter.Modifiers
If modifier.Kind() <> SyntaxKind.ByValKeyword Then
builder.Append(modifier.Text)
builder.Append(" "c)
End If
Next
If parameter.AsClause?.Type IsNot Nothing Then
AppendTokens(parameter.AsClause.Type, builder)
End If
First = False
Next
End Sub
Private Function GetAccessibility(node As SyntaxNode, modifiers As SyntaxTokenList) As Accessibility
Dim sawFriend = False
For Each modifier In modifiers
Select Case modifier.Kind()
Case SyntaxKind.PublicKeyword : Return Accessibility.Public
Case SyntaxKind.PrivateKeyword : Return Accessibility.Private
Case SyntaxKind.ProtectedKeyword : Return Accessibility.Protected
Case SyntaxKind.FriendKeyword
sawFriend = True
Continue For
End Select
Next
If sawFriend Then
Return Accessibility.Internal
End If
' No accessibility modifiers
Select Case node.Parent.Kind()
Case SyntaxKind.ClassBlock
' In a class, fields and shared-constructors are private by default,
' everything Else Is Public
If node.Kind() = SyntaxKind.FieldDeclaration Then
Return Accessibility.Private
End If
If node.Kind() = SyntaxKind.ConstructorBlock AndAlso
DirectCast(node, ConstructorBlockSyntax).SubNewStatement.Modifiers.Any(SyntaxKind.SharedKeyword) Then
Return Accessibility.Private
End If
Return Accessibility.Public
Case SyntaxKind.StructureBlock, SyntaxKind.InterfaceBlock, SyntaxKind.ModuleBlock
' Everything in a struct/interface/module is public
Return Accessibility.Public
End Select
' Otherwise, it's internal
Return Accessibility.Internal
End Function
Private Function GetInheritanceNames(typeBlock As TypeBlockSyntax) As ImmutableArray(Of String)
Dim builder = ArrayBuilder(Of String).GetInstance()
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册