public async TPL.Task <IEnumerable <INavigableItem> > FindDefinitionsAsync(Document document, int position, CancellationToken cancellationToken) { var definitionItems = await GetDefinitionItemsAsync(document, position, cancellationToken).ConfigureAwait(false); if (definitionItems.IsDefaultOrEmpty) { return(ImmutableArray <INavigableItem> .Empty); } var navigableItems = ImmutableArray.CreateBuilder <INavigableItem>(); foreach (var documentSpan in definitionItems.SelectMany(di => di.SourceSpans)) { var declaredSymbolInfo = new DeclaredSymbolInfo(Roslyn.Utilities.StringTable.GetInstance(), string.Empty, string.Empty, string.Empty, string.Empty, DeclaredSymbolInfoKind.Class, Accessibility.NotApplicable, documentSpan.SourceSpan, ImmutableArray <string> .Empty); navigableItems.Add(NavigableItemFactory.GetItemFromDeclaredSymbolInfo(declaredSymbolInfo, documentSpan.Document)); } return(navigableItems.ToArray()); }
public SearchResult(Document document, DeclaredSymbolInfo declaredSymbolInfo, string kind, MatchKind matchKind, bool isCaseSensitive, INavigableItem navigableItem) { _document = document; _declaredSymbolInfo = declaredSymbolInfo; Kind = kind; MatchKind = matchKind; IsCaseSensitive = isCaseSensitive; NavigableItem = navigableItem; SecondarySort = ConstructSecondarySortString(declaredSymbolInfo); var declaredNavigableItem = navigableItem as NavigableItemFactory.DeclaredSymbolNavigableItem; Debug.Assert(declaredNavigableItem != null); _lazySummary = new Lazy <string>(() => declaredNavigableItem.Symbol?.GetDocumentationComment()?.SummaryText); _lazyAdditionalInfo = new Lazy <string>(() => { switch (declaredSymbolInfo.Kind) { case DeclaredSymbolInfoKind.Class: case DeclaredSymbolInfoKind.Enum: case DeclaredSymbolInfoKind.Interface: case DeclaredSymbolInfoKind.Module: case DeclaredSymbolInfoKind.Struct: return(EditorFeaturesResources.Project + document.Project.Name); default: return(EditorFeaturesResources.Type + declaredSymbolInfo.ContainerDisplayName); } }); }
public SearchResult( Document document, DeclaredSymbolInfo declaredSymbolInfo, string kind, NavigateToMatchKind matchKind, bool isCaseSensitive, INavigableItem navigableItem, ImmutableArray <TextSpan> nameMatchSpans) { _document = document; _declaredSymbolInfo = declaredSymbolInfo; Kind = kind; MatchKind = matchKind; IsCaseSensitive = isCaseSensitive; NavigableItem = navigableItem; NameMatchSpans = nameMatchSpans; SecondarySort = ConstructSecondarySortString(document, declaredSymbolInfo); var declaredNavigableItem = navigableItem as NavigableItemFactory.DeclaredSymbolNavigableItem; Debug.Assert(declaredNavigableItem != null); _lazyAdditionalInfo = new Lazy <string>(() => { switch (declaredSymbolInfo.Kind) { case DeclaredSymbolInfoKind.Class: case DeclaredSymbolInfoKind.Enum: case DeclaredSymbolInfoKind.Interface: case DeclaredSymbolInfoKind.Module: case DeclaredSymbolInfoKind.Struct: return(FeaturesResources.project_space + document.Project.Name); default: return(FeaturesResources.type_space + declaredSymbolInfo.ContainerDisplayName); } }); }
public DeclaredSymbolInfo GetDeclaredSymbolInfo( Huffman huffman, IList<AssemblyInfo> assemblies, IList<string> projects) { var result = new DeclaredSymbolInfo { AssemblyNumber = AssemblyNumber, Glyph = Glyph, Name = Name }; if (assemblies != null && AssemblyNumber < assemblies.Count) { var assembly = assemblies[AssemblyNumber]; result.AssemblyName = assembly.AssemblyName; if (projects != null && assembly.ProjectKey >= 0 && assembly.ProjectKey < projects.Count) { result.ProjectFilePath = projects[assembly.ProjectKey]; } } result.ID = ID; result.Kind = GetKind(Glyph); if (huffman != null && Description != IntPtr.Zero) { result.Description = huffman.Uncompress(Description); } return result; }
private static int Sorter(DeclaredSymbolInfo left, DeclaredSymbolInfo right) { if (left == right) { return 0; } if (left == null || right == null) { return 1; } int comparison = StringComparer.OrdinalIgnoreCase.Compare(left.Name, right.Name); if (comparison != 0) { return comparison; } comparison = left.KindRank.CompareTo(right.KindRank); if (comparison != 0) { return comparison; } comparison = StringComparer.Ordinal.Compare(left.Name, right.Name); if (comparison != 0) { return comparison; } comparison = left.AssemblyNumber.CompareTo(right.AssemblyNumber); return comparison; }
protected override DeclaredSymbolInfo?GetTypeDeclarationInfo( SyntaxNode container, TypeDeclarationSyntax typeDeclaration, StringTable stringTable, string containerDisplayName, string fullyQualifiedContainerName) { // If this is a part of partial type that only contains nested types, then we don't make an info type for // it. That's because we effectively think of this as just being a virtual container just to hold the nested // types, and not something someone would want to explicitly navigate to itself. Similar to how we think of // namespaces. if (typeDeclaration.Modifiers.Any(SyntaxKind.PartialKeyword) && typeDeclaration.Members.Any() && typeDeclaration.Members.All(m => m is BaseTypeDeclarationSyntax)) { return(null); } return(DeclaredSymbolInfo.Create( stringTable, typeDeclaration.Identifier.ValueText, GetTypeParameterSuffix(typeDeclaration.TypeParameterList), containerDisplayName, fullyQualifiedContainerName, typeDeclaration.Modifiers.Any(SyntaxKind.PartialKeyword), typeDeclaration.Kind() switch { SyntaxKind.ClassDeclaration => DeclaredSymbolInfoKind.Class, SyntaxKind.InterfaceDeclaration => DeclaredSymbolInfoKind.Interface, SyntaxKind.StructDeclaration => DeclaredSymbolInfoKind.Struct, SyntaxKind.RecordDeclaration => DeclaredSymbolInfoKind.Record, SyntaxKind.RecordStructDeclaration => DeclaredSymbolInfoKind.RecordStruct, _ => throw ExceptionUtilities.UnexpectedValue(typeDeclaration.Kind()), },
private void NoMatch(DeclaredSymbolInfo declaredSymbolInfo, params string[] queryStrings) { foreach (var queryString in queryStrings) { Match(declaredSymbolInfo, queryString, false); } }
private static string ConstructSecondarySortString( Document document, DeclaredSymbolInfo declaredSymbolInfo) { var parts = ArrayBuilder <string> .GetInstance(); try { parts.Add(declaredSymbolInfo.ParameterCount.ToString("X4")); parts.Add(declaredSymbolInfo.TypeParameterCount.ToString("X4")); parts.Add(declaredSymbolInfo.Name); // For partial types, we break up the file name into pieces. i.e. If we have // Outer.cs and Outer.Inner.cs then we add "Outer" and "Outer Inner" to // the secondary sort string. That way "Outer.cs" will be weighted above // "Outer.Inner.cs" var fileName = Path.GetFileNameWithoutExtension(document.FilePath ?? ""); parts.AddRange(fileName.Split(s_dotArray)); return(string.Join(" ", parts)); } finally { parts.Free(); } }
public DeclaredSymbolNavigableItem(Document document, DeclaredSymbolInfo declaredSymbolInfo, CancellationToken cancellationToken) { Document = document; _declaredSymbolInfo = declaredSymbolInfo; _lazySymbol = new Lazy <ISymbol>(() => declaredSymbolInfo.GetSymbolAsync(document, cancellationToken).ConfigureAwait(false).GetAwaiter().GetResult()); _lazyDisplayName = new Lazy <string>(() => { if (Symbol == null) { return(null); } var symbolDisplayService = Document.GetLanguageService <ISymbolDisplayService>(); switch (Symbol.Kind) { case SymbolKind.NamedType: return(symbolDisplayService.ToDisplayString(Symbol, s_shortFormatWithModifiers)); case SymbolKind.Method: return(Symbol.IsStaticConstructor() ? symbolDisplayService.ToDisplayString(Symbol, s_shortFormatWithModifiers) : symbolDisplayService.ToDisplayString(Symbol, s_shortFormat)); default: return(symbolDisplayService.ToDisplayString(Symbol, s_shortFormat)); } }); }
public DeclaredSymbolNavigableItem(Document document, DeclaredSymbolInfo declaredSymbolInfo) { Document = document; _declaredSymbolInfo = declaredSymbolInfo; // Cancellation isn't supported when computing the various properties that depend on the symbol, hence // CancellationToken.None. _lazySymbol = new Lazy <ISymbol>(() => declaredSymbolInfo.GetSymbolAsync(document, CancellationToken.None).ConfigureAwait(false).GetAwaiter().GetResult()); _lazyDisplayString = new Lazy <string>(() => { try { if (Symbol == null) { return(null); } return(GetSymbolDisplayString(Document.Project, Symbol)); } catch (Exception e) when(FatalError.Report(e)) { throw ExceptionUtilities.Unreachable; } }); }
public SearchResult( Document document, DeclaredSymbolInfo declaredSymbolInfo, string kind, NavigateToMatchKind matchKind, bool isCaseSensitive, INavigableItem navigableItem, ImmutableArray <TextSpan> nameMatchSpans) { Document = document; DeclaredSymbolInfo = declaredSymbolInfo; Kind = kind; MatchKind = matchKind; IsCaseSensitive = isCaseSensitive; NavigableItem = navigableItem; NameMatchSpans = nameMatchSpans; _lazyAdditionalInfo = new Lazy <string>(() => { switch (declaredSymbolInfo.Kind) { case DeclaredSymbolInfoKind.Class: case DeclaredSymbolInfoKind.Enum: case DeclaredSymbolInfoKind.Interface: case DeclaredSymbolInfoKind.Module: case DeclaredSymbolInfoKind.Struct: if (!declaredSymbolInfo.IsNestedType) { return(string.Format(FeaturesResources.project_0, document.Project.Name)); } break; } return(string.Format(FeaturesResources.in_0_project_1, declaredSymbolInfo.ContainerDisplayName, document.Project.Name)); }); }
public IndexEntry(DeclaredSymbolInfo symbolInfo) { AssemblyNumber = symbolInfo.AssemblyNumber; Glyph = symbolInfo.Glyph; Name = string.Intern(symbolInfo.Name); ID = symbolInfo.ID; Description = IntPtr.Zero; }
private static async Task <ISymbol> TryResolveAsync( Document document, DeclaredSymbolInfo info, ConcurrentSet <SemanticModel> cachedModels, CancellationToken cancellationToken) { var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); cachedModels.Add(semanticModel); return(info.TryResolve(semanticModel, cancellationToken)); }
private static IEnumerable <PatternMatch> TryGetDotSeparatedPatternMatches( PatternMatcher patternMatcher, string[] dotSeparatedPatternComponents, DeclaredSymbolInfo declaredSymbolInfo) { if (dotSeparatedPatternComponents == null || declaredSymbolInfo.FullyQualifiedContainerName == null || declaredSymbolInfo.Name == null) { return(null); } // First, check that the last part of the dot separated pattern matches the name of the // declared symbol. If not, then there's no point in proceeding and doing the more // expensive work. var symbolNameMatch = patternMatcher.MatchPattern(GetSearchName(declaredSymbolInfo), dotSeparatedPatternComponents.Last()); if (symbolNameMatch == null) { return(null); } // So far so good. Now break up the container for the symbol and check if all // the dotted parts match up correctly. var totalMatch = symbolNameMatch.ToList(); var containerParts = declaredSymbolInfo.FullyQualifiedContainerName .Split(DotArray, StringSplitOptions.RemoveEmptyEntries) .ToList(); // -1 because the last part was checked against hte name, and only the rest // of the parts are checked against the container. if (dotSeparatedPatternComponents.Length - 1 > containerParts.Count) { // There weren't enough container parts to match against the pattern parts. // So this definitely doesn't match. return(null); } for (int i = dotSeparatedPatternComponents.Length - 2, j = containerParts.Count - 1; i >= 0; i--, j--) { var dotPattern = dotSeparatedPatternComponents[i]; var containerName = containerParts[j]; var containerMatch = patternMatcher.MatchPattern(containerName, dotPattern); if (containerMatch == null) { // This container didn't match the pattern piece. So there's no match at all. return(null); } totalMatch.AddRange(containerMatch); } // Success, this symbol's full name matched against the dotted name the user was asking // about. return(totalMatch); }
private static string ConstructSecondarySortString(DeclaredSymbolInfo declaredSymbolInfo) { var secondarySortString = string.Concat( declaredSymbolInfo.ParameterCount.ToString("X4"), declaredSymbolInfo.TypeParameterCount.ToString("X4"), declaredSymbolInfo.Name); return(secondarySortString); }
private void Insert(NamespaceTreeNode root, DeclaredSymbolInfo type) { var namespaceString = type.GetNamespace(); var parts = namespaceString.Split(new[] { '.' }, StringSplitOptions.RemoveEmptyEntries); var nodeWhereToInsert = GetOrCreateNode(root, parts, 0); // { is to sort types after namespaces var inserted = nodeWhereToInsert.GetOrCreate("{" + type.Name); inserted.TypeDeclaration = type; }
private bool FilterDottedNames(DeclaredSymbolInfo symbol) { if (this.Namespace == null) { return(FilterAssemblies(symbol) || FilterDotSeparatedNames.Any(n => FilterNamespace(symbol, n))); } else { return(FilterAssemblies(symbol) && FilterNamespace(symbol, this.Namespace)); } }
private static string GetSearchName(DeclaredSymbolInfo declaredSymbolInfo) { if (declaredSymbolInfo.Kind == DeclaredSymbolInfoKind.Indexer && declaredSymbolInfo.Name == WellKnownMemberNames.Indexer) { return("this"); } else { return(declaredSymbolInfo.Name); } }
private static async Task ProcessSymbolInfo( Document document, DeclaredSymbolInfo info, SymbolAndProjectIdSet typesToSearchFor, InheritanceQuery inheritanceQuery, ConcurrentSet <SemanticModel> cachedModels, Func <SymbolAndProjectIdSet, INamedTypeSymbol, bool> typeImmediatelyMatches, SymbolAndProjectIdSet result, CancellationToken cancellationToken) { var projectId = document.Project.Id; // If we're searching for enums/structs/delegates, then we can just look at the kind of // the info to see if we have a match. if ((inheritanceQuery.DerivesFromSystemEnum && info.Kind == DeclaredSymbolInfoKind.Enum) || (inheritanceQuery.DerivesFromSystemValueType && info.Kind == DeclaredSymbolInfoKind.Struct) || (inheritanceQuery.DerivesFromSystemMulticastDelegate && info.Kind == DeclaredSymbolInfoKind.Delegate)) { var symbol = await TryResolveAsync(document, info, cachedModels, cancellationToken).ConfigureAwait(false) as INamedTypeSymbol; if (symbol != null) { result.Add(SymbolAndProjectId.Create(symbol, projectId)); } } else if (inheritanceQuery.DerivesFromSystemObject && info.Kind == DeclaredSymbolInfoKind.Class) { // Searching for types derived from 'Object' needs to be handled specially. // There may be no indication in source what the type actually derives from. // Also, we can't just look for an empty inheritance list. We may have // something like: "class C : IFoo". This type derives from object, despite // having a non-empty list. var symbol = await TryResolveAsync(document, info, cachedModels, cancellationToken).ConfigureAwait(false) as INamedTypeSymbol; if (symbol?.BaseType?.SpecialType == SpecialType.System_Object) { result.Add(SymbolAndProjectId.Create(symbol, projectId)); } } else if (AnyInheritanceNamesMatch(info, inheritanceQuery.TypeNames)) { // Looks like we have a potential match. Actually check if the symbol is viable. var symbol = await TryResolveAsync(document, info, cachedModels, cancellationToken).ConfigureAwait(false) as INamedTypeSymbol; if (symbol != null) { if (typeImmediatelyMatches(typesToSearchFor, symbol)) { result.Add(SymbolAndProjectId.Create(symbol, projectId)); } } } }
protected override void AddDeclaredSymbolInfosWorker( SyntaxNode container, MemberDeclarationSyntax node, StringTable stringTable, ArrayBuilder <DeclaredSymbolInfo> declaredSymbolInfos, Dictionary <string, string> aliases, Dictionary <string, ArrayBuilder <int> > extensionMethodInfo, string containerDisplayName, string fullyQualifiedContainerName, CancellationToken cancellationToken) { // If this is a part of partial type that only contains nested types, then we don't make an info type for // it. That's because we effectively think of this as just being a virtual container just to hold the nested // types, and not something someone would want to explicitly navigate to itself. Similar to how we think of // namespaces. if (node is TypeDeclarationSyntax typeDeclaration && typeDeclaration.Modifiers.Any(SyntaxKind.PartialKeyword) && typeDeclaration.Members.Any() && typeDeclaration.Members.All(m => m is BaseTypeDeclarationSyntax)) { return; } switch (node.Kind()) { case SyntaxKind.ClassDeclaration: case SyntaxKind.RecordDeclaration: case SyntaxKind.RecordStructDeclaration: case SyntaxKind.InterfaceDeclaration: case SyntaxKind.StructDeclaration: var typeDecl = (TypeDeclarationSyntax)node; declaredSymbolInfos.Add(DeclaredSymbolInfo.Create( stringTable, typeDecl.Identifier.ValueText, GetTypeParameterSuffix(typeDecl.TypeParameterList), containerDisplayName, fullyQualifiedContainerName, typeDecl.Modifiers.Any(SyntaxKind.PartialKeyword), node.Kind() switch { SyntaxKind.ClassDeclaration => DeclaredSymbolInfoKind.Class, SyntaxKind.RecordDeclaration => DeclaredSymbolInfoKind.Record, SyntaxKind.InterfaceDeclaration => DeclaredSymbolInfoKind.Interface, SyntaxKind.StructDeclaration => DeclaredSymbolInfoKind.Struct, SyntaxKind.RecordStructDeclaration => DeclaredSymbolInfoKind.RecordStruct, _ => throw ExceptionUtilities.UnexpectedValue(node.Kind()), }, GetAccessibility(container, typeDecl.Modifiers), typeDecl.Identifier.Span, GetInheritanceNames(stringTable, typeDecl.BaseList), IsNestedType(typeDecl))); return;
private static bool AnyInheritanceNamesMatch( DeclaredSymbolInfo info, HashSet <string> typeNamesToSearchFor) { foreach (var name in info.InheritanceNames) { if (typeNamesToSearchFor.Contains(name)) { return(true); } } return(false); }
private static void Match(DeclaredSymbolInfo declaredSymbolInfo, string queryString, bool expected) { var query = new Query(queryString); bool actual = query.Filter(declaredSymbolInfo) && query.Interpretations.Any(i => declaredSymbolInfo.Name.StartsWith( i.CoreSearchTerm, StringComparison.OrdinalIgnoreCase) && i.Filter(declaredSymbolInfo)); Assert.AreEqual(expected, actual, queryString); }
private static INavigateToSearchResult ConvertResult( bool containsDots, DeclaredSymbolInfo declaredSymbolInfo, Document document, PatternMatches matches) { var matchKind = GetNavigateToMatchKind(containsDots, matches); // A match is considered to be case sensitive if all its constituent pattern matches are // case sensitive. var isCaseSensitive = matches.All(m => m.IsCaseSensitive); var kind = GetItemKind(declaredSymbolInfo); var navigableItem = NavigableItemFactory.GetItemFromDeclaredSymbolInfo(declaredSymbolInfo, document); return(new SearchResult(document, declaredSymbolInfo, kind, matchKind, isCaseSensitive, navigableItem)); }
public override bool TryGetDeclaredSymbolInfo( StringTable stringTable, SyntaxNode node, string rootNamespace, out DeclaredSymbolInfo declaredSymbolInfo ) { // If this is a part of partial type that only contains nested types, then we don't make an info type for // it. That's because we effectively think of this as just being a virtual container just to hold the nested // types, and not something someone would want to explicitly navigate to itself. Similar to how we think of // namespaces. if ( node is TypeDeclarationSyntax typeDeclaration && typeDeclaration.Modifiers.Any(SyntaxKind.PartialKeyword) && typeDeclaration.Members.Any() && typeDeclaration.Members.All(m => m is BaseTypeDeclarationSyntax) ) { declaredSymbolInfo = default; return(false); } switch (node.Kind()) { case SyntaxKind.ClassDeclaration: case SyntaxKind.RecordDeclaration: case SyntaxKind.InterfaceDeclaration: case SyntaxKind.StructDeclaration: var typeDecl = (TypeDeclarationSyntax)node; declaredSymbolInfo = DeclaredSymbolInfo.Create( stringTable, typeDecl.Identifier.ValueText, GetTypeParameterSuffix(typeDecl.TypeParameterList), GetContainerDisplayName(node.Parent), GetFullyQualifiedContainerName(node.Parent), typeDecl.Modifiers.Any(SyntaxKind.PartialKeyword), node.Kind() switch { SyntaxKind.ClassDeclaration => DeclaredSymbolInfoKind.Class, SyntaxKind.RecordDeclaration => DeclaredSymbolInfoKind.Record, SyntaxKind.InterfaceDeclaration => DeclaredSymbolInfoKind.Interface, SyntaxKind.StructDeclaration => DeclaredSymbolInfoKind.Struct, _ => throw ExceptionUtilities.UnexpectedValue(node.Kind()), }, GetAccessibility(typeDecl, typeDecl.Modifiers), typeDecl.Identifier.Span, GetInheritanceNames(stringTable, typeDecl.BaseList), IsNestedType(typeDecl) ); return(true);
private static INavigateToSearchResult ConvertResult( DeclaredSymbolInfo declaredSymbolInfo, Document document, ArrayBuilder <PatternMatch> nameMatches, ArrayBuilder <PatternMatch> containerMatches) { var matchKind = GetNavigateToMatchKind(nameMatches); // A match is considered to be case sensitive if all its constituent pattern matches are // case sensitive. var isCaseSensitive = nameMatches.All(m => m.IsCaseSensitive) && containerMatches.All(m => m.IsCaseSensitive); var kind = GetItemKind(declaredSymbolInfo); var navigableItem = NavigableItemFactory.GetItemFromDeclaredSymbolInfo(declaredSymbolInfo, document); return(new SearchResult( document, declaredSymbolInfo, kind, matchKind, isCaseSensitive, navigableItem, nameMatches.SelectMany(m => m.MatchedSpans).ToImmutableArray())); }
private static bool IsNamedType(DeclaredSymbolInfo info) { switch (info.Kind) { case DeclaredSymbolInfoKind.Class: case DeclaredSymbolInfoKind.Record: case DeclaredSymbolInfoKind.Enum: case DeclaredSymbolInfoKind.Interface: case DeclaredSymbolInfoKind.Module: case DeclaredSymbolInfoKind.Struct: return(true); default: return(false); } }
private static string GetItemKind(DeclaredSymbolInfo declaredSymbolInfo) { switch (declaredSymbolInfo.Kind) { case DeclaredSymbolInfoKind.Class: return(NavigateToItemKind.Class); case DeclaredSymbolInfoKind.Constant: return(NavigateToItemKind.Constant); case DeclaredSymbolInfoKind.Delegate: return(NavigateToItemKind.Delegate); case DeclaredSymbolInfoKind.Enum: return(NavigateToItemKind.Enum); case DeclaredSymbolInfoKind.EnumMember: return(NavigateToItemKind.EnumItem); case DeclaredSymbolInfoKind.Event: return(NavigateToItemKind.Event); case DeclaredSymbolInfoKind.Field: return(NavigateToItemKind.Field); case DeclaredSymbolInfoKind.Interface: return(NavigateToItemKind.Interface); case DeclaredSymbolInfoKind.Constructor: case DeclaredSymbolInfoKind.ExtensionMethod: case DeclaredSymbolInfoKind.Method: return(NavigateToItemKind.Method); case DeclaredSymbolInfoKind.Module: return(NavigateToItemKind.Module); case DeclaredSymbolInfoKind.Indexer: case DeclaredSymbolInfoKind.Property: return(NavigateToItemKind.Property); case DeclaredSymbolInfoKind.Struct: return(NavigateToItemKind.Structure); default: return(Contract.FailWithReturn <string>("Unknown declaration kind " + declaredSymbolInfo.Kind)); } }
private static string GetItemKind(DeclaredSymbolInfo declaredSymbolInfo) { switch (declaredSymbolInfo.Kind) { case DeclaredSymbolInfoKind.Class: return(NavigateToItemKind.Class); case DeclaredSymbolInfoKind.Constant: return(NavigateToItemKind.Constant); case DeclaredSymbolInfoKind.Delegate: return(NavigateToItemKind.Delegate); case DeclaredSymbolInfoKind.Enum: return(NavigateToItemKind.Enum); case DeclaredSymbolInfoKind.EnumMember: return(NavigateToItemKind.EnumItem); case DeclaredSymbolInfoKind.Event: return(NavigateToItemKind.Event); case DeclaredSymbolInfoKind.Field: return(NavigateToItemKind.Field); case DeclaredSymbolInfoKind.Interface: return(NavigateToItemKind.Interface); case DeclaredSymbolInfoKind.Constructor: case DeclaredSymbolInfoKind.ExtensionMethod: case DeclaredSymbolInfoKind.Method: return(NavigateToItemKind.Method); case DeclaredSymbolInfoKind.Module: return(NavigateToItemKind.Module); case DeclaredSymbolInfoKind.Indexer: case DeclaredSymbolInfoKind.Property: return(NavigateToItemKind.Property); case DeclaredSymbolInfoKind.Struct: return(NavigateToItemKind.Structure); default: throw ExceptionUtilities.UnexpectedValue(declaredSymbolInfo.Kind); } }
private bool FilterAssemblies(DeclaredSymbolInfo symbol) { if (!this.FilterDotSeparatedNames.Any()) { return(true); } foreach (var assemblyName in this.FilterDotSeparatedNames) { if (symbol.AssemblyName.IndexOf(assemblyName, StringComparison.OrdinalIgnoreCase) != -1) { return(true); } } return(false); }
private bool FilterProjects(DeclaredSymbolInfo symbol) { if (!this.Paths.Any()) { return(true); } foreach (var path in this.Paths) { if (symbol.ProjectFilePath == null || symbol.ProjectFilePath.IndexOf(path, StringComparison.OrdinalIgnoreCase) == -1) { return(false); } } return(true); }
private static void AddResultIfMatch( Document document, DeclaredSymbolInfo declaredSymbolInfo, PatternMatcher nameMatcher, PatternMatcher containerMatcherOpt, ArrayBuilder <PatternMatch> nameMatches, ArrayBuilder <PatternMatch> containerMatches, ArrayBuilder <SearchResult> result, CancellationToken cancellationToken) { nameMatches.Clear(); containerMatches.Clear(); cancellationToken.ThrowIfCancellationRequested(); if (nameMatcher.AddMatches(declaredSymbolInfo.Name, nameMatches) && containerMatcherOpt?.AddMatches(declaredSymbolInfo.FullyQualifiedContainerName, containerMatches) != false) { result.Add(ConvertResult( declaredSymbolInfo, document, nameMatches, containerMatches)); } }
private static bool FilterNamespace(DeclaredSymbolInfo symbol, string namespacePrefix) { var description = symbol.Description; int openParen = description.IndexOf('('); if (openParen > -1) { // if the description contains (, we should only search before it, to not accidentally // match any of the parameters that may follow afterwards description = description.Substring(0, openParen); } if (description.IndexOf(namespacePrefix, StringComparison.OrdinalIgnoreCase) != -1) { return true; } return false; }
private static string ComputeAdditionalInfo(Document document, DeclaredSymbolInfo info, ImmutableArray <Project> additionalMatchingProjects) { var projectName = ComputeProjectName(document, additionalMatchingProjects); // For partial types, state what file they're in so the user can disambiguate the results. if (info.IsPartial) { return(IsNonNestedNamedType(info) ? string.Format(FeaturesResources._0_dash_1, document.Name, projectName) : string.Format(FeaturesResources.in_0_1_2, info.ContainerDisplayName, document.Name, projectName)); } else { return(IsNonNestedNamedType(info) ? string.Format(FeaturesResources.project_0, projectName) : string.Format(FeaturesResources.in_0_project_1, info.ContainerDisplayName, projectName)); } }
public SearchResult( Document document, DeclaredSymbolInfo declaredSymbolInfo, string kind, NavigateToMatchKind matchKind, bool isCaseSensitive, INavigableItem navigableItem, ImmutableArray <TextSpan> nameMatchSpans, ImmutableArray <Project> additionalMatchingProjects) { Name = declaredSymbolInfo.Name; Kind = kind; MatchKind = matchKind; IsCaseSensitive = isCaseSensitive; NavigableItem = navigableItem; NameMatchSpans = nameMatchSpans; AdditionalInformation = ComputeAdditionalInformation(document, declaredSymbolInfo, additionalMatchingProjects); SecondarySort = ConstructSecondarySortString(document, declaredSymbolInfo); }
/// <summary> /// This defines the ordering of results based on the kind of symbol and other heuristics /// </summary> private int SymbolSorter(DeclaredSymbolInfo left, DeclaredSymbolInfo right, Query query) { if (left == right) { return(0); } if (left == null || right == null) { return(1); } var comparison = left.MatchLevel.CompareTo(right.MatchLevel); if (comparison != 0) { return(comparison); } comparison = left.KindRank.CompareTo(right.KindRank); if (comparison != 0) { return(comparison); } if (left.Name != null && right.Name != null) { comparison = string.Compare(left.Name, right.Name, StringComparison.Ordinal); if (comparison != 0) { return(comparison); } } comparison = left.AssemblyNumber.CompareTo(right.AssemblyNumber); if (comparison != 0) { return(comparison); } comparison = StringComparer.Ordinal.Compare(left.Description, right.Description); return(comparison); }
//[TestMethod] public void LoadIndex() { Index index = ReadIndex(); var matches = index.FindSymbols("Microsoft.CodeAnalysis.CSharp.Symbols.SourceNamedTypeSymbol"); var expected = new DeclaredSymbolInfo() { AssemblyName = "Microsoft.CodeAnalysis.CSharp", Description = "Microsoft.CodeAnalysis.CSharp.Symbols.SourceNamedTypeSymbol", Glyph = 1, ID = 6622120691603058343UL, // { 167, 174, 195, 250, 174, 127, 230, 91 } Kind = "class", Name = "SourceNamedTypeSymbol", ProjectFilePath = "Source\\Compilers\\CSharp\\Source\\CSharpCodeAnalysis.csproj" }; Verify(matches, expected); var query = new Query("System.Core"); index.FindAssemblies(query); Assert.AreEqual("System.Core", query.ResultAssemblies.First().AssemblyName); }
/// <summary> /// This defines the ordering of results based on the kind of symbol and other heuristics /// </summary> private int SymbolSorter(DeclaredSymbolInfo left, DeclaredSymbolInfo right, Query query) { if (left == right) { return 0; } if (left == null || right == null) { return 1; } var comparison = left.MatchLevel.CompareTo(right.MatchLevel); if (comparison != 0) { return comparison; } comparison = left.KindRank.CompareTo(right.KindRank); if (comparison != 0) { return comparison; } if (left.Name != null && right.Name != null) { comparison = left.Name.CompareTo(right.Name); if (comparison != 0) { return comparison; } } comparison = left.AssemblyNumber.CompareTo(right.AssemblyNumber); if (comparison != 0) { return comparison; } comparison = StringComparer.Ordinal.Compare(left.Description, right.Description); return comparison; }
public void ReadDeclarationLines() { DeclaredSymbols = new Dictionary<ulong, DeclaredSymbolInfo>(); var assemblyIndex = Path.Combine(ProjectDestinationFolder, Constants.DeclaredSymbolsFileName + ".txt"); if (!File.Exists(assemblyIndex)) { return; } var declarationLines = File.ReadAllLines(assemblyIndex); foreach (var declarationLine in declarationLines) { var symbolInfo = new DeclaredSymbolInfo(declarationLine); symbolInfo.AssemblyName = this.AssemblyId; if (symbolInfo.IsValid) { DeclaredSymbols[symbolInfo.ID] = symbolInfo; } } }
private static string GetGlyph(DeclaredSymbolInfo symbol) { var result = symbol.Glyph; if (result == 196) { return "CSharp"; } else if (result == 195) { return "VB"; } else if (result == 227) { return "xaml"; } else if (result == 228) { return "TypeScript"; } return result.ToString(); }
public static void WriteSymbol(DeclaredSymbolInfo symbol, StringBuilder sb) { var url = symbol.GetUrl(); sb.AppendFormat("<a href=\"{0}\" target=\"s\"><div class=\"resultItem\" onClick=\"resultClick(this);\">", url); sb.Append("<div class=\"resultLine\">"); sb.AppendFormat("<img src=\"/content/icons/{0}\" height=\"16\" width=\"16\" />", GetGlyph(symbol) + ".png"); sb.AppendFormat("<div class=\"resultKind\">{0}</div>", symbol.Kind); sb.AppendFormat("<div class=\"resultName\">{0}</div>", Markup.HtmlEscape(symbol.Name)); sb.AppendLine("</div>"); sb.AppendFormat("<div class=\"resultDescription\">{0}</div>", Markup.HtmlEscape(symbol.Description)); sb.AppendLine(); sb.AppendLine("</div></a>"); }
public static void ParseDeclaredSymbol(string separated, DeclaredSymbolInfo declaredSymbolInfo) { ushort glyph = ushort.MaxValue; // to save space and avoid extra field, this indicates an invalid symbol var parts = separated.Split(';'); if (parts.Length == 5) { declaredSymbolInfo.Name = string.Intern(parts[0]); declaredSymbolInfo.ID = HexStringToULong(parts[1]); declaredSymbolInfo.Kind = string.Intern(parts[2]); declaredSymbolInfo.Description = parts[3]; ushort.TryParse(parts[4], out glyph); } declaredSymbolInfo.Glyph = glyph; }
private bool FilterSymbolKinds(DeclaredSymbolInfo symbol) { if (!this.SymbolKinds.Any()) { return true; } foreach (var symbolKind in this.SymbolKinds) { if (symbol.Kind == symbolKind) { return true; } if (symbolKind == SymbolKindText.Type && SymbolKindText.IsType(symbol.Kind)) { return true; } } return false; }
private bool FilterProjects(DeclaredSymbolInfo symbol) { if (!this.Paths.Any()) { return true; } foreach (var path in this.Paths) { if (symbol.ProjectFilePath.IndexOf(path, StringComparison.OrdinalIgnoreCase) == -1) { return false; } } return true; }
public bool Filter(DeclaredSymbolInfo symbol) { return FilterDottedNames(symbol) && FilterWords(symbol); }
private bool FilterWords(DeclaredSymbolInfo symbol) { if (this.FilterNames.Count == 0) { return true; } foreach (var word in this.FilterNames) { if (symbol.Name.IndexOf(word, StringComparison.OrdinalIgnoreCase) == -1 && (symbol.AssemblyName == null || symbol.AssemblyName.IndexOf(word, StringComparison.OrdinalIgnoreCase) == -1) && (symbol.ProjectFilePath == null || symbol.ProjectFilePath.IndexOf(word, StringComparison.OrdinalIgnoreCase) == -1)) { return false; } } return true; }
private bool FilterDottedNames(DeclaredSymbolInfo symbol) { if (this.Namespace == null) { return FilterAssemblies(symbol) || FilterDotSeparatedNames.Any(n => FilterNamespace(symbol, n)); } else { return FilterAssemblies(symbol) && FilterNamespace(symbol, this.Namespace); } }
private bool FilterAssemblies(DeclaredSymbolInfo symbol) { if (!this.FilterDotSeparatedNames.Any()) { return true; } foreach (var assemblyName in this.FilterDotSeparatedNames) { if (symbol.AssemblyName.IndexOf(assemblyName, StringComparison.OrdinalIgnoreCase) != -1) { return true; } } return false; }
public bool Filter(DeclaredSymbolInfo symbol) { return FilterSymbolKinds(symbol) && FilterProjects(symbol); }
private void WriteType(DeclaredSymbolInfo typeDeclaration, StreamWriter sw, string className, string pathPrefix) { string typeUrl = typeDeclaration.GetUrl(); sw.Write(string.Format("<div class=\"{3}\"><a class=\"tDN\" href=\"{0}\" target=\"s\"><img class=\"tDNI\" src=\"{4}content/icons/{2}.png\" />{1}</a></div>", typeUrl, Markup.HtmlEscape(typeDeclaration.Name), typeDeclaration.Glyph, className, pathPrefix)); }
public static void WriteDeclaredSymbol(BinaryWriter writer, DeclaredSymbolInfo symbol, Huffman huffman) { Write7BitEncodedInt(writer, symbol.AssemblyNumber); writer.Write(symbol.Name); writer.Write(symbol.ID); WriteBytes(writer, huffman.Compress(symbol.Description)); Write7BitEncodedInt(writer, symbol.Glyph); }