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());
        }
Esempio n. 2
0
            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);
                    }
                });
            }
Esempio n. 4
0
        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;
        }
Esempio n. 5
0
        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;
        }
Esempio n. 6
0
        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();
                }
            }
Esempio n. 9
0
            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));
                    }
                });
            }
Esempio n. 10
0
            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;
                    }
                });
            }
Esempio n. 11
0
            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));
                });
            }
Esempio n. 12
0
 public IndexEntry(DeclaredSymbolInfo symbolInfo)
 {
     AssemblyNumber = symbolInfo.AssemblyNumber;
     Glyph = symbolInfo.Glyph;
     Name = string.Intern(symbolInfo.Name);
     ID = symbolInfo.ID;
     Description = IntPtr.Zero;
 }
Esempio n. 13
0
        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));
        }
Esempio n. 14
0
        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);
        }
Esempio n. 15
0
            private static string ConstructSecondarySortString(DeclaredSymbolInfo declaredSymbolInfo)
            {
                var secondarySortString = string.Concat(
                    declaredSymbolInfo.ParameterCount.ToString("X4"),
                    declaredSymbolInfo.TypeParameterCount.ToString("X4"),
                    declaredSymbolInfo.Name);

                return(secondarySortString);
            }
Esempio n. 16
0
        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;
        }
Esempio n. 17
0
 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);
     }
 }
Esempio n. 19
0
        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));
                    }
                }
            }
        }
Esempio n. 20
0
        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;
Esempio n. 21
0
        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);
Esempio n. 25
0
        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()));
        }
Esempio n. 26
0
            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));
            }
        }
Esempio n. 28
0
        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);
            }
        }
Esempio n. 29
0
        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);
        }
Esempio n. 30
0
        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);
        }
Esempio n. 31
0
        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));
            }
        }
Esempio n. 32
0
        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;
        }
Esempio n. 33
0
            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);
 }
Esempio n. 35
0
        /// <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);
        }
Esempio n. 37
0
        /// <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;
        }
Esempio n. 38
0
        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;
                }
            }
        }
Esempio n. 39
0
        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();
        }
Esempio n. 40
0
 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>");
 }
Esempio n. 41
0
        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;
        }
Esempio n. 42
0
        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;
        }
Esempio n. 43
0
        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;
        }
Esempio n. 44
0
 public bool Filter(DeclaredSymbolInfo symbol)
 {
     return
         FilterDottedNames(symbol) &&
         FilterWords(symbol);
 }
Esempio n. 45
0
        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;
        }
Esempio n. 46
0
 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);
     }
 }
Esempio n. 47
0
        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;
        }
Esempio n. 48
0
 public bool Filter(DeclaredSymbolInfo symbol)
 {
     return
         FilterSymbolKinds(symbol) &&
         FilterProjects(symbol);
 }
Esempio n. 49
0
 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));
 }
Esempio n. 50
0
 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);
 }