public int GetIndexForSymbolId(SymbolKey id)
 {
     int nextId;
     _nextIds.TryGetValue(id, out nextId);
     _nextIds[id] = nextId + 1;
     return nextId;
 }
예제 #2
0
 private CodeTypeRef(CodeModelState state, object parent, ProjectId projectId, ITypeSymbol typeSymbol)
     : base(state)
 {
     _parentHandle = new ParentHandle<object>(parent);
     _projectId = projectId;
     _symbolId = typeSymbol.GetSymbolKey();
 }
        private ExternalNamespaceEnumerator(CodeModelState state, ProjectId projectId, SymbolKey namespaceSymbolId)
        {
            _state = state;
            _projectId = projectId;
            _namespaceSymbolId = namespaceSymbolId;

            _childEnumerator = ChildrenOfNamespace(state, projectId, namespaceSymbolId).GetEnumerator();
        }
예제 #4
0
 protected AbstractCallFinder(ISymbol symbol, Project project, IAsynchronousOperationListener asyncListener, CallHierarchyProvider provider)
 {
     _asyncListener = asyncListener;
     _symbol = symbol.GetSymbolKey();
     this.SymbolName = symbol.Name;
     _project = project;
     this.Provider = provider;
 }
예제 #5
0
            public Task<SymbolMappingResult> MapSymbolAsync(Document document, SymbolKey symbolId, CancellationToken cancellationToken)
            {
                var workspace = document.Project.Solution.Workspace as MetadataAsSourceWorkspace;
                if (workspace == null)
                {
                    throw new ArgumentException(EditorFeaturesResources.DocumentMustBeContainedInWorkspace, nameof(document));
                }

                return workspace.FileService.MapSymbolAsync(document, symbolId, cancellationToken);
            }
 public MetadataDefinitionTreeItem(Workspace workspace, ISymbol definition, ProjectId referencingProjectId, ushort glyphIndex)
     : base(glyphIndex)
 {
     _workspace = workspace;
     _referencingProjectId = referencingProjectId;
     _symbolKey = definition.GetSymbolKey();
     _assemblyName = definition.ContainingAssembly.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat);
     _symbolDefinition = definition.ToDisplayString(definitionDisplayFormat);
     this.DisplayText = $"[{_assemblyName}] {_symbolDefinition}";
 }
예제 #7
0
 public DefinitionPeekableItem(
     Workspace workspace, ProjectId projectId, SymbolKey symbolKey,
     IPeekResultFactory peekResultFactory,
     IMetadataAsSourceFileService metadataAsSourceService)
     : base(peekResultFactory)
 {
     _workspace = workspace;
     _projectId = projectId;
     _symbolKey = symbolKey;
     _metadataAsSourceFileService = metadataAsSourceService;
 }
            public async Task<SymbolMappingResult> MapSymbolAsync(Document document, SymbolKey symbolId, CancellationToken cancellationToken)
            {
                var compilation = await document.Project.GetCompilationAsync(cancellationToken).ConfigureAwait(false);
                var symbol = symbolId.Resolve(compilation, cancellationToken: cancellationToken).Symbol;
                if (symbol != null)
                {
                    return new SymbolMappingResult(document.Project, symbol);
                }

                return null;
            }
예제 #9
0
        internal static ISymbol ResolveSymbol(ISymbol originalSymbol, Compilation targetCompilation, SymbolKeyComparison comparison)
        {
            var sid = SymbolKey.Create(originalSymbol, CancellationToken.None);

            // Verify that serialization works.
            var serialized = sid.ToString();
            var deserialized = new SymbolKey(serialized);
            var comparer = SymbolKey.GetComparer(ignoreCase: false, ignoreAssemblyKeys: false);
            Assert.True(comparer.Equals(sid, deserialized));

            var symInfo = sid.Resolve(targetCompilation, (comparison & SymbolKeyComparison.IgnoreAssemblyIds) == SymbolKeyComparison.IgnoreAssemblyIds);
            return symInfo.Symbol;
        }
예제 #10
0
 public CallHierarchyItem(ISymbol symbol, ProjectId projectId, IEnumerable<AbstractCallFinder> finders, Func<ImageSource> glyphCreator, CallHierarchyProvider provider, IEnumerable<Location> callsites, Workspace workspace)
 {
     _symbolId = symbol.GetSymbolKey();
     _projectId = projectId;
     _finders = finders;
     _containingTypeName = symbol.ContainingType.ToDisplayString(ContainingTypeFormat);
     _containingNamespaceName = symbol.ContainingNamespace.ToDisplayString(ContainingNamespaceFormat);
     _glyphCreator = glyphCreator;
     _name = symbol.ToDisplayString(MemberNameFormat);
     _provider = provider;
     _callsites = callsites.Select(l => new CallHierarchyDetail(l, workspace));
     _sortText = symbol.ToDisplayString();
     _workspace = workspace;
 }
 public MetadataDefinitionItem(
     ImmutableArray<string> tags,
     ImmutableArray<TaggedText> displayParts,
     bool displayIfNoReferences,
     Solution solution, ISymbol definition)
     : base(tags, displayParts,
           GetOriginationParts(definition),
           ImmutableArray<DocumentLocation>.Empty,
           displayIfNoReferences)
 {
     _workspace = solution.Workspace;
     _symbolKey = definition.GetSymbolKey();
     _symbolAssemblyIdentity = definition.ContainingAssembly?.Identity;
 }
예제 #12
0
 public NavigationBarSymbolItem(
     string text,
     Glyph glyph,
     IList<TextSpan> spans,
     SymbolKey navigationSymbolId,
     int? navigationSymbolIndex,
     IList<NavigationBarItem> childItems = null,
     int indent = 0,
     bool bolded = false,
     bool grayed = false)
     : base(text, glyph, spans, childItems, indent, bolded, grayed)
 {
     this.NavigationSymbolId = navigationSymbolId;
     this.NavigationSymbolIndex = navigationSymbolIndex;
 }
예제 #13
0
        protected SymbolListItem(ProjectId projectId, ISymbol symbol, string displayText, string fullNameText, string searchText, bool isHidden)
            : base(projectId, symbol.GetStandardGlyphGroup(), symbol.GetStandardGlyphItem(), isHidden)
        {
            _symbolKey = symbol.GetSymbolKey();
            _accessibility = symbol.DeclaredAccessibility;
            _displayText = displayText;
            _fullNameText = fullNameText;
            _searchText = searchText;

            _supportsGoToDefinition = symbol.Kind != SymbolKind.Namespace
                ? symbol.Locations.Any(l => l.IsInSource)
                : false;

            _supportsFindAllReferences = symbol.Kind != SymbolKind.Namespace;
        }
 public MemberInsertionCompletionItem(
     CompletionListProvider provider,
     string displayText,
     TextSpan filterSpan,
     Func<CancellationToken, Task<ImmutableArray<SymbolDisplayPart>>> descriptionFactory,
     Glyph? glyph,
     DeclarationModifiers modifiers,
     int line,
     SymbolKey symbolId,
     SyntaxToken token)
     : base(provider, displayText, filterSpan, descriptionFactory, glyph)
 {
     this.Modifiers = modifiers;
     this.Line = line;
     this.SymbolId = symbolId;
     this.Token = token;
 }
예제 #15
0
        public static async Task<Location> GetLocationInGeneratedSourceAsync(SymbolKey symbolId, Document generatedDocument, CancellationToken cancellationToken)
        {
            var location = symbolId.Resolve(
                await generatedDocument.Project.GetCompilationAsync(cancellationToken).ConfigureAwait(false),
                ignoreAssemblyKey: true, cancellationToken: cancellationToken)
                .GetAllSymbols()
                .Select(s => s.Locations.Where(loc => loc.IsInSource).FirstOrDefault())
                .WhereNotNull()
                .FirstOrDefault();

            if (location == null)
            {
                // If we cannot find the symbol, then put the caret at the beginning of the file.
                var tree = await generatedDocument.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);
                location = Location.Create(tree, new TextSpan(0, 0));
            }

            return location;
        }
예제 #16
0
        private void NavigateOnForegroundThread(SourceLocation sourceLocation, SymbolKey? symbolId, Project project, Document document)
        {
            AssertIsForeground();

            // Notify of navigation so third parties can intercept the navigation
            if (symbolId != null)
            {
                var symbolNavigationService = _workspace.Services.GetService<ISymbolNavigationService>();
                var symbol = symbolId.Value.Resolve(project.GetCompilationAsync(CancellationToken.None).WaitAndGetResult(CancellationToken.None)).Symbol;

                // Do not allow third party navigation to types or constructors
                if (symbol != null &&
                    !(symbol is ITypeSymbol) &&
                    !symbol.IsConstructor() &&
                    symbolNavigationService.TrySymbolNavigationNotify(symbol, project.Solution))
                {
                    return;
                }
            }

            if (sourceLocation.IsValid)
            {
                // We must find the right document in this project. This may not be the
                // ContextDocumentId if you have a partial member that is shown under one
                // document, but only exists in the other

                if (document != null)
                {
                    var editorWorkspace = document.Project.Solution.Workspace;
                    var navigationService = editorWorkspace.Services.GetService<IDocumentNavigationService>();
                    navigationService.TryNavigateToLineAndOffset(
                        editorWorkspace,
                        document.Id,
                        sourceLocation.StartPosition.Line,
                        sourceLocation.StartPosition.Character);
                }
            }
        }
예제 #17
0
        internal static IEnumerable<EnvDTE.CodeElement> ChildrenOfNamespace(CodeModelState state, ProjectId projectId, SymbolKey namespaceSymbolId)
        {
            var project = state.Workspace.CurrentSolution.GetProject(projectId);
            if (project == null)
            {
                throw Exceptions.ThrowEFail();
            }

            var namespaceSymbol = namespaceSymbolId.Resolve(project.GetCompilationAsync().Result).Symbol as INamespaceSymbol;
            if (namespaceSymbol == null)
            {
                throw Exceptions.ThrowEFail();
            }

            var containingAssembly = project.GetCompilationAsync().Result.Assembly;

            foreach (var child in namespaceSymbol.GetMembers())
            {
                if (child is INamespaceSymbol)
                {
                    yield return (EnvDTE.CodeElement)ExternalCodeNamespace.Create(state, projectId, (INamespaceSymbol)child);
                }
                else
                {
                    var namedType = (INamedTypeSymbol)child;

                    if (namedType.IsAccessibleWithin(containingAssembly))
                    {
                        if (namedType.Locations.Any(l => l.IsInMetadata || l.IsInSource))
                        {
                            yield return state.CodeModelService.CreateCodeType(state, projectId, namedType);
                        }
                    }
                }
            }
        }
예제 #18
0
        private static ImmutableArray <SerializableImportCompletionItem> ConvertSymbolsToCompletionItems(
            Compilation compilation, ImmutableArray <IMethodSymbol> extentsionMethodSymbols, ImmutableArray <ITypeSymbol> targetTypeSymbols, CancellationToken cancellationToken)
        {
            Dictionary <ITypeSymbol, bool> typeConvertibilityCache = new();

            using var _1 = PooledDictionary <INamespaceSymbol, string> .GetInstance(out var namespaceNameCache);

            using var _2 = PooledDictionary <(string containingNamespace, string methodName, bool isGeneric), (IMethodSymbol bestSymbol, int overloadCount, bool includeInTargetTypedCompletion)>
                           .GetInstance(out var overloadMap);

            // Aggregate overloads
            foreach (var symbol in extentsionMethodSymbols)
            {
                cancellationToken.ThrowIfCancellationRequested();

                IMethodSymbol bestSymbol;
                int           overloadCount;
                var           includeInTargetTypedCompletion = ShouldIncludeInTargetTypedCompletion(compilation, symbol, targetTypeSymbols, typeConvertibilityCache);

                var containingNamespacename = GetFullyQualifiedNamespaceName(symbol.ContainingNamespace, namespaceNameCache);
                var overloadKey             = (containingNamespacename, symbol.Name, isGeneric : symbol.Arity > 0);

                // Select the overload convertible to any targeted type (if any) and with minimum number of parameters to display
                if (overloadMap.TryGetValue(overloadKey, out var currentValue))
                {
                    if (currentValue.includeInTargetTypedCompletion == includeInTargetTypedCompletion)
                    {
                        bestSymbol = currentValue.bestSymbol.Parameters.Length > symbol.Parameters.Length ? symbol : currentValue.bestSymbol;
                    }
                    else if (currentValue.includeInTargetTypedCompletion)
                    {
                        bestSymbol = currentValue.bestSymbol;
                    }
                    else
                    {
                        bestSymbol = symbol;
                    }

                    overloadCount = currentValue.overloadCount + 1;
                    includeInTargetTypedCompletion = includeInTargetTypedCompletion || currentValue.includeInTargetTypedCompletion;
                }
                else
                {
                    bestSymbol    = symbol;
                    overloadCount = 1;
                }

                overloadMap[overloadKey] = (bestSymbol, overloadCount, includeInTargetTypedCompletion);
            }

            // Then convert symbols into completion items
            using var _3 = ArrayBuilder <SerializableImportCompletionItem> .GetInstance(out var itemsBuilder);

            foreach (var((containingNamespace, _, _), (bestSymbol, overloadCount, includeInTargetTypedCompletion)) in overloadMap)
            {
                // To display the count of additional overloads, we need to subtract total by 1.
                var item = new SerializableImportCompletionItem(
                    SymbolKey.CreateString(bestSymbol, cancellationToken),
                    bestSymbol.Name,
                    bestSymbol.Arity,
                    bestSymbol.GetGlyph(),
                    containingNamespace,
                    additionalOverloadCount: overloadCount - 1,
                    includeInTargetTypedCompletion);

                itemsBuilder.Add(item);
            }

            return(itemsBuilder.ToImmutable());
        }
예제 #19
0
        private static async Task <ImmutableArray <TaggedText> > GetDescriptionAsync(Document document, int position, SymbolKey symbolKey, SymbolDescriptionOptions options, CancellationToken cancellationToken)
        {
            var semanticModel = await document.GetRequiredSemanticModelAsync(cancellationToken).ConfigureAwait(false);

            var symbol = symbolKey.Resolve(semanticModel.Compilation, cancellationToken: cancellationToken).Symbol;

            if (symbol != null)
            {
                var symbolDisplayService = document.GetRequiredLanguageService <ISymbolDisplayService>();

                var parts = new List <TaggedText>();

                var groups = await symbolDisplayService.ToDescriptionGroupsAsync(
                    semanticModel, position, ImmutableArray.Create(symbol), options, cancellationToken).ConfigureAwait(false);

                parts.AddRange(groups[SymbolDescriptionGroups.MainDescription]);

                var formatter     = document.GetRequiredLanguageService <IDocumentationCommentFormattingService>();
                var documentation = symbol.GetDocumentationParts(semanticModel, position, formatter, cancellationToken);

                if (documentation.Any())
                {
                    parts.AddLineBreak();
                    parts.AddRange(documentation);
                }

                if (groups.TryGetValue(SymbolDescriptionGroups.StructuralTypes, out var anonymousTypes))
                {
                    if (!anonymousTypes.IsDefaultOrEmpty)
                    {
                        parts.AddLineBreak();
                        parts.AddLineBreak();
                        parts.AddRange(anonymousTypes);
                    }
                }

                return(parts.ToImmutableArray());
            }

            return(default);
예제 #20
0
            public UniqueDocumentKey(string filePath, MetadataId?metadataId, string language, SymbolKey symbolId, bool signaturesOnly)
            {
                Contract.ThrowIfNull(filePath);

                _filePath       = filePath;
                _metadataId     = metadataId;
                _language       = language;
                _symbolId       = symbolId;
                _signaturesOnly = signaturesOnly;
            }
예제 #21
0
 internal ExternalNamespaceCollection(CodeModelState state, object parent, ProjectId projectId, INamespaceSymbol namespaceSymbol)
     : base(state, parent)
 {
     _projectId         = projectId;
     _namespaceSymbolId = namespaceSymbol.GetSymbolKey();
 }
예제 #22
0
 internal ExternalNamespaceCollection(CodeModelState state, object parent, ProjectId projectId, INamespaceSymbol namespaceSymbol)
     : base(state, parent)
 {
     _projectId = projectId;
     _namespaceSymbolId = namespaceSymbol.GetSymbolKey();
 }
예제 #23
0
        public async Task <SignatureHelpItems?> GetItemsAsync(
            Document document, int position, SignatureHelpTriggerInfo triggerInfo, CancellationToken cancellationToken)
        {
            var itemsForCurrentDocument = await GetItemsWorkerAsync(document, position, triggerInfo, cancellationToken).ConfigureAwait(false);

            if (itemsForCurrentDocument == null)
            {
                return(itemsForCurrentDocument);
            }

            var relatedDocuments = await FindActiveRelatedDocumentsAsync(position, document, cancellationToken).ConfigureAwait(false);

            if (relatedDocuments.IsEmpty)
            {
                return(itemsForCurrentDocument);
            }

            var totalProjects = relatedDocuments.Select(d => d.Project.Id).Concat(document.Project.Id);

            var semanticModel = await document.ReuseExistingSpeculativeModelAsync(position, cancellationToken).ConfigureAwait(false);

            var compilation = semanticModel.Compilation;

            var finalItems = new List <SignatureHelpItem>();

            foreach (var item in itemsForCurrentDocument.Items)
            {
                if (item is not SymbolKeySignatureHelpItem symbolKeyItem ||
                    symbolKeyItem.SymbolKey is not SymbolKey symbolKey ||
                    symbolKey.Resolve(compilation, ignoreAssemblyKey: true, cancellationToken).Symbol is not ISymbol symbol)
                {
                    finalItems.Add(item);
                    continue;
                }

                // If the symbol is an instantiated generic method, ensure we use its original
                // definition for symbol key resolution in related compilations.
                if (symbol is IMethodSymbol methodSymbol && methodSymbol.IsGenericMethod && methodSymbol != methodSymbol.OriginalDefinition)
                {
                    symbolKey = SymbolKey.Create(methodSymbol.OriginalDefinition, cancellationToken);
                }

                var invalidProjectsForCurrentSymbol = new List <ProjectId>();
                foreach (var relatedDocument in relatedDocuments)
                {
                    // Try to resolve symbolKey in each related compilation,
                    // unresolvable key means the symbol is unavailable in the corresponding project.
                    var relatedSemanticModel = await relatedDocument.ReuseExistingSpeculativeModelAsync(position, cancellationToken).ConfigureAwait(false);

                    if (symbolKey.Resolve(relatedSemanticModel.Compilation, ignoreAssemblyKey: true, cancellationToken).Symbol == null)
                    {
                        invalidProjectsForCurrentSymbol.Add(relatedDocument.Project.Id);
                    }
                }

                var platformData = new SupportedPlatformData(invalidProjectsForCurrentSymbol, totalProjects, document.Project.Solution.Workspace);
                finalItems.Add(UpdateItem(item, platformData));
            }

            return(new SignatureHelpItems(
                       finalItems, itemsForCurrentDocument.ApplicableSpan,
                       itemsForCurrentDocument.ArgumentIndex,
                       itemsForCurrentDocument.ArgumentCount,
                       itemsForCurrentDocument.ArgumentName,
                       itemsForCurrentDocument.SelectedItemIndex));
        }
예제 #24
0
 public static InlineParameterNameHintsTag Create(string text, double lineHeight, TextFormattingRunProperties format,
                                                  ITextView textView, SnapshotSpan span, SymbolKey key,
                                                  InlineParameterNameHintsTaggerProvider taggerProvider)
 {
     return(new InlineParameterNameHintsTag(CreateElement(text, lineHeight, format), textView,
                                            span, key, taggerProvider));
 }
예제 #25
0
 public static string EncodeSymbol(ISymbol symbol)
 {
     return(SymbolKey.CreateString(symbol));
 }
 fields.Select(f => SymbolKey.CreateString(f, cancellationToken)).ToArray(),
예제 #27
0
 private static ISymbol DecodeSymbol(string id, Compilation compilation)
 {
     return(SymbolKey.ResolveString(id, compilation).GetAnySymbol());
 }
        public static async Task <(ImmutableArray <SerializableImportCompletionItem>, StatisticCounter)> GetUnimportedExtensionMethodsInRemoteProcessAsync(
            RemoteHostClient client,
            Document document,
            int position,
            ITypeSymbol receiverTypeSymbol,
            ISet <string> namespaceInScope,
            bool forceIndexCreation,
            CancellationToken cancellationToken)
        {
            var project = document.Project;

            var(serializableItems, counter) = (await client.TryRunCodeAnalysisRemoteValueAsync <(IList <SerializableImportCompletionItem>, StatisticCounter)>(
                                                   project.Solution,
                                                   nameof(IRemoteExtensionMethodImportCompletionService.GetUnimportedExtensionMethodsAsync),
                                                   new object[] { document.Id, position, SymbolKey.CreateString(receiverTypeSymbol), namespaceInScope.ToArray(), forceIndexCreation },
                                                   cancellationToken).ConfigureAwait(false)).GetValueOrDefault();


            return(serializableItems.ToImmutableArray(), counter);
        }
예제 #29
0
 private ExternalMemberCollection(CodeModelState state, object parent, ProjectId projectId, ITypeSymbol typeSymbol)
     : base(state, parent)
 {
     _projectId    = projectId;
     _typeSymbolId = typeSymbol.GetSymbolKey();
 }
예제 #30
0
        private static bool TryGetDependentTypes(ConditionalWeakTable<Compilation, ConcurrentDictionary<SymbolKey, List<SymbolKey>>> cache, Compilation compilation, SymbolKey typeId, out List<SymbolKey> dependentTypeIds)
        {
            dependentTypeIds = null;

            ConcurrentDictionary<SymbolKey, List<SymbolKey>> dictionary;

            return cache.TryGetValue(compilation, out dictionary) &&
                   dictionary.TryGetValue(typeId, out dependentTypeIds);
        }
예제 #31
0
        private async Task <UniqueDocumentKey> GetUniqueDocumentKey(Project project, INamedTypeSymbol topLevelNamedType, CancellationToken cancellationToken)
        {
            var compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false);

            var peMetadataReference = compilation.GetMetadataReference(topLevelNamedType.ContainingAssembly) as PortableExecutableReference;

            if (peMetadataReference.FilePath != null)
            {
                return(new UniqueDocumentKey(peMetadataReference.FilePath, project.Language, SymbolKey.Create(topLevelNamedType, cancellationToken)));
            }
            else
            {
                return(new UniqueDocumentKey(topLevelNamedType.ContainingAssembly.Identity, project.Language, SymbolKey.Create(topLevelNamedType, cancellationToken)));
            }
        }
예제 #32
0
 public static string EncodeSymbol(ISymbol symbol)
 => SymbolKey.CreateString(symbol);
예제 #33
0
            public UniqueDocumentKey(AssemblyIdentity assemblyIdentity, string language, SymbolKey symbolId)
            {
                Contract.ThrowIfNull(assemblyIdentity);

                _assemblyIdentity = assemblyIdentity;
                _language         = language;
                _symbolId         = symbolId;
            }
        private ExternalNamespaceEnumerator(CodeModelState state, ProjectId projectId, SymbolKey namespaceSymbolId)
        {
            _state             = state;
            _projectId         = projectId;
            _namespaceSymbolId = namespaceSymbolId;

            _childEnumerator = ChildrenOfNamespace(state, projectId, namespaceSymbolId).GetEnumerator();
        }
        internal static IEnumerator Create(CodeModelState state, ProjectId projectId, SymbolKey namespaceSymbolId)
        {
            var newEnumerator = new ExternalNamespaceEnumerator(state, projectId, namespaceSymbolId);

            return((IEnumerator)ComAggregate.CreateAggregatedObject(newEnumerator));
        }
예제 #36
0
 public void NavigateTo(SymbolKey id, Project project, CancellationToken cancellationToken)
 {
     var compilation = project.GetCompilationAsync(cancellationToken).WaitAndGetResult(cancellationToken);
     var resolution = id.Resolve(compilation, cancellationToken: cancellationToken);
     project.Solution.Workspace.Services.GetService<ISymbolNavigationService>().TryNavigateToSymbol(resolution.Symbol, project, usePreviewTab: true, cancellationToken: cancellationToken);
 }
예제 #37
0
        public static Task <Location> GetLocationInGeneratedSourceAsync(ISymbol symbol, Document generatedDocument, CancellationToken cancellationToken)
        {
            var symbolKey = SymbolKey.Create(symbol, cancellationToken);

            return(MetadataAsSourceHelpers.GetLocationInGeneratedSourceAsync(symbolKey, generatedDocument, cancellationToken));
        }
예제 #38
0
        public void NavigateTo(SymbolKey id, Project project, CancellationToken cancellationToken)
        {
            var compilation = project.GetCompilationAsync(cancellationToken).WaitAndGetResult(cancellationToken);
            var resolution = id.Resolve(compilation, cancellationToken: cancellationToken);
            var workspace = project.Solution.Workspace;
            var options = workspace.Options.WithChangedOption(NavigationOptions.PreferProvisionalTab, true);
            var symbolNavigationService = workspace.Services.GetService<ISymbolNavigationService>();

            symbolNavigationService.TryNavigateToSymbol(resolution.Symbol, project, options, cancellationToken);
        }
예제 #39
0
        public static async Task <SerializableUnimportedExtensionMethods?> GetUnimportedExtensionMethodsAsync(
            Document document,
            int position,
            ITypeSymbol receiverTypeSymbol,
            ISet <string> namespaceInScope,
            ImmutableArray <ITypeSymbol> targetTypesSymbols,
            bool forceCacheCreation,
            bool hideAdvancedMembers,
            CancellationToken cancellationToken)
        {
            var project = document.Project;
            var client  = await RemoteHostClient.TryGetClientAsync(project, cancellationToken).ConfigureAwait(false);

            if (client != null)
            {
                var receiverTypeSymbolKeyData = SymbolKey.CreateString(receiverTypeSymbol, cancellationToken);
                var targetTypesSymbolKeyData  = targetTypesSymbols.SelectAsArray(s => SymbolKey.CreateString(s, cancellationToken));

                // Call the project overload.  Add-import-for-extension-method doesn't search outside of the current
                // project cone.
                var result = await client.TryInvokeAsync <IRemoteExtensionMethodImportCompletionService, SerializableUnimportedExtensionMethods?>(
                    project,
                    (service, solutionInfo, cancellationToken) => service.GetUnimportedExtensionMethodsAsync(
                        solutionInfo, document.Id, position, receiverTypeSymbolKeyData, namespaceInScope.ToImmutableArray(),
                        targetTypesSymbolKeyData, forceCacheCreation, hideAdvancedMembers, cancellationToken),
                    cancellationToken).ConfigureAwait(false);

                return(result.HasValue ? result.Value : null);
            }
            else
            {
                return(await GetUnimportedExtensionMethodsInCurrentProcessAsync(
                           document, position, receiverTypeSymbol, namespaceInScope, targetTypesSymbols, forceCacheCreation, hideAdvancedMembers, isRemote : false, cancellationToken)
                       .ConfigureAwait(false));
            }
        }
예제 #40
0
 private ExternalMemberCollection(CodeModelState state, object parent, ProjectId projectId, ITypeSymbol typeSymbol)
     : base(state, parent)
 {
     _projectId = projectId;
     _typeSymbolId = typeSymbol.GetSymbolKey();
 }
        internal static IEnumerable <EnvDTE.CodeElement> ChildrenOfNamespace(CodeModelState state, ProjectId projectId, SymbolKey namespaceSymbolId)
        {
            var project = state.Workspace.CurrentSolution.GetProject(projectId);

            if (project == null)
            {
                throw Exceptions.ThrowEFail();
            }

            var namespaceSymbol = namespaceSymbolId.Resolve(project.GetCompilationAsync().Result).Symbol as INamespaceSymbol;

            if (namespaceSymbol == null)
            {
                throw Exceptions.ThrowEFail();
            }

            var containingAssembly = project.GetCompilationAsync().Result.Assembly;

            foreach (var child in namespaceSymbol.GetMembers())
            {
                if (child is INamespaceSymbol)
                {
                    yield return((EnvDTE.CodeElement)ExternalCodeNamespace.Create(state, projectId, (INamespaceSymbol)child));
                }
                else
                {
                    var namedType = (INamedTypeSymbol)child;

                    if (namedType.IsAccessibleWithin(containingAssembly))
                    {
                        if (namedType.Locations.Any(l => l.IsInMetadata || l.IsInSource))
                        {
                            yield return(state.CodeModelService.CreateCodeType(state, projectId, namedType));
                        }
                    }
                }
            }
        }
예제 #42
0
            public UniqueDocumentKey(AssemblyIdentity assemblyIdentity, MetadataId?metadataId, string language, SymbolKey symbolId, bool signaturesOnly)
            {
                Contract.ThrowIfNull(assemblyIdentity);

                _assemblyIdentity = assemblyIdentity;
                _metadataId       = metadataId;
                _language         = language;
                _symbolId         = symbolId;
                _signaturesOnly   = signaturesOnly;
            }
예제 #43
0
            public UniqueDocumentKey(string filePath, MetadataId?metadataId, string language, SymbolKey symbolId, bool allowDecompilation)
            {
                Contract.ThrowIfNull(filePath);

                _filePath           = filePath;
                _metadataId         = metadataId;
                _language           = language;
                _symbolId           = symbolId;
                _allowDecompilation = allowDecompilation;
            }
예제 #44
0
            public UniqueDocumentKey(AssemblyIdentity assemblyIdentity, MetadataId?metadataId, string language, SymbolKey symbolId, bool allowDecompilation)
            {
                Contract.ThrowIfNull(assemblyIdentity);

                _assemblyIdentity   = assemblyIdentity;
                _metadataId         = metadataId;
                _language           = language;
                _symbolId           = symbolId;
                _allowDecompilation = allowDecompilation;
            }
예제 #45
0
        public async Task <MetadataAsSourceFile> GetGeneratedFileAsync(Project project, ISymbol symbol, bool allowDecompilation, CancellationToken cancellationToken = default)
        {
            if (project == null)
            {
                throw new ArgumentNullException(nameof(project));
            }

            if (symbol == null)
            {
                throw new ArgumentNullException(nameof(symbol));
            }

            if (symbol.Kind == SymbolKind.Namespace)
            {
                throw new ArgumentException(EditorFeaturesResources.symbol_cannot_be_a_namespace, nameof(symbol));
            }

            symbol = symbol.GetOriginalUnreducedDefinition();

            MetadataAsSourceGeneratedFileInfo fileInfo;
            Location?navigateLocation  = null;
            var      topLevelNamedType = MetadataAsSourceHelpers.GetTopLevelContainingNamedType(symbol);
            var      symbolId          = SymbolKey.Create(symbol, cancellationToken);
            var      compilation       = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false);

            using (await _gate.DisposableWaitAsync(cancellationToken).ConfigureAwait(false))
            {
                InitializeWorkspace(project);
                Contract.ThrowIfNull(_workspace);

                var infoKey = await GetUniqueDocumentKey(project, topLevelNamedType, allowDecompilation, cancellationToken).ConfigureAwait(false);

                fileInfo = _keyToInformation.GetOrAdd(infoKey, _ => new MetadataAsSourceGeneratedFileInfo(GetRootPathWithGuid_NoLock(), project, topLevelNamedType, allowDecompilation));

                _generatedFilenameToInformation[fileInfo.TemporaryFilePath] = fileInfo;

                if (!File.Exists(fileInfo.TemporaryFilePath))
                {
                    // We need to generate this. First, we'll need a temporary project to do the generation into. We
                    // avoid loading the actual file from disk since it doesn't exist yet.
                    var temporaryProjectInfoAndDocumentId = fileInfo.GetProjectInfoAndDocumentId(_workspace, loadFileFromDisk: false);
                    var temporaryDocument = _workspace.CurrentSolution.AddProject(temporaryProjectInfoAndDocumentId.Item1)
                                            .GetDocument(temporaryProjectInfoAndDocumentId.Item2);

                    Contract.ThrowIfNull(temporaryDocument, "The temporary ProjectInfo didn't contain the document it said it would.");

                    var useDecompiler = allowDecompilation;
                    if (useDecompiler)
                    {
                        useDecompiler = !symbol.ContainingAssembly.GetAttributes().Any(attribute => attribute.AttributeClass.Name == nameof(SuppressIldasmAttribute) &&
                                                                                       attribute.AttributeClass.ToNameDisplayString() == typeof(SuppressIldasmAttribute).FullName);
                    }

                    if (useDecompiler)
                    {
                        try
                        {
                            var decompiledSourceService = temporaryDocument.GetLanguageService <IDecompiledSourceService>();
                            if (decompiledSourceService != null)
                            {
                                temporaryDocument = await decompiledSourceService.AddSourceToAsync(temporaryDocument, compilation, symbol, cancellationToken).ConfigureAwait(false);
                            }
                            else
                            {
                                useDecompiler = false;
                            }
                        }
                        catch (Exception e) when(FatalError.ReportWithoutCrashUnlessCanceled(e))
                        {
                            useDecompiler = false;
                        }
                    }

                    if (!useDecompiler)
                    {
                        var sourceFromMetadataService = temporaryDocument.Project.LanguageServices.GetRequiredService <IMetadataAsSourceService>();
                        temporaryDocument = await sourceFromMetadataService.AddSourceToAsync(temporaryDocument, compilation, symbol, cancellationToken).ConfigureAwait(false);
                    }

                    // We have the content, so write it out to disk
                    var text = await temporaryDocument.GetTextAsync(cancellationToken).ConfigureAwait(false);

                    // Create the directory. It's possible a parallel deletion is happening in another process, so we may have
                    // to retry this a few times.
                    var directoryToCreate = Path.GetDirectoryName(fileInfo.TemporaryFilePath);
                    while (!Directory.Exists(directoryToCreate))
                    {
                        try
                        {
                            Directory.CreateDirectory(directoryToCreate);
                        }
                        catch (DirectoryNotFoundException)
                        {
                        }
                        catch (UnauthorizedAccessException)
                        {
                        }
                    }

                    using (var textWriter = new StreamWriter(fileInfo.TemporaryFilePath, append: false, encoding: fileInfo.Encoding))
                    {
                        text.Write(textWriter);
                    }

                    // Mark read-only
                    new FileInfo(fileInfo.TemporaryFilePath).IsReadOnly = true;

                    // Locate the target in the thing we just created
                    navigateLocation = await MetadataAsSourceHelpers.GetLocationInGeneratedSourceAsync(symbolId, temporaryDocument, cancellationToken).ConfigureAwait(false);
                }

                // If we don't have a location yet, then that means we're re-using an existing file. In this case, we'll want to relocate the symbol.
                if (navigateLocation == null)
                {
                    navigateLocation = await RelocateSymbol_NoLock(fileInfo, symbolId, cancellationToken).ConfigureAwait(false);
                }
            }

            var documentName = string.Format(
                "{0} [{1}]",
                topLevelNamedType.Name,
                EditorFeaturesResources.from_metadata);

            var documentTooltip = topLevelNamedType.ToDisplayString(new SymbolDisplayFormat(typeQualificationStyle: SymbolDisplayTypeQualificationStyle.NameAndContainingTypesAndNamespaces));

            return(new MetadataAsSourceFile(fileInfo.TemporaryFilePath, navigateLocation, documentName, documentTooltip));
        }
예제 #46
0
 public static Func <Document, CancellationToken, Task <ImmutableArray <TaggedText> > >?GetDescriptionFunction(int position, SymbolKey symbolKey, SymbolDescriptionOptions options)
 => (document, cancellationToken) => GetDescriptionAsync(document, position, symbolKey, options, cancellationToken);
예제 #47
0
        private static bool TryGetDependentTypes(ConditionalWeakTable <Compilation, ConcurrentDictionary <SymbolKey, List <SymbolKey> > > cache, Compilation compilation, SymbolKey typeId, out List <SymbolKey> dependentTypeIds)
        {
            dependentTypeIds = null;

            ConcurrentDictionary <SymbolKey, List <SymbolKey> > dictionary;

            return(cache.TryGetValue(compilation, out dictionary) &&
                   dictionary.TryGetValue(typeId, out dependentTypeIds));
        }
예제 #48
0
 protected AbstractGenerateCodeItem(RoslynNavigationBarItemKind kind, string text, Glyph glyph, SymbolKey destinationTypeSymbolKey)
     : base(kind, text, glyph, bolded: false, grayed: false, indent: 0, childItems: default)
 {
     DestinationTypeSymbolKey = destinationTypeSymbolKey;
 }
예제 #49
0
        private static List <SymbolKey> GetOrAddDependentTypes(ConditionalWeakTable <Compilation, ConcurrentDictionary <SymbolKey, List <SymbolKey> > > cache, Compilation compilation, SymbolKey typeId, List <SymbolKey> dependentTypeIds)
        {
            List <SymbolKey> result;

            if (TryGetDependentTypes(cache, compilation, typeId, out result))
            {
                return(result);
            }
            else
            {
                return(cache.GetValue(compilation, s_createSymbolDictionary)
                       .GetOrAdd(typeId, dependentTypeIds));
            }
        }
예제 #50
0
 private static List<SymbolKey> GetOrAddDependentTypes(ConditionalWeakTable<Compilation, ConcurrentDictionary<SymbolKey, List<SymbolKey>>> cache, Compilation compilation, SymbolKey typeId, List<SymbolKey> dependentTypeIds)
 {
     List<SymbolKey> result;
     if (TryGetDependentTypes(cache, compilation, typeId, out result))
     {
         return result;
     }
     else
     {
         return cache.GetValue(compilation, s_createSymbolDictionary)
                     .GetOrAdd(typeId, dependentTypeIds);
     }
 }
예제 #51
0
 internal static IEnumerator Create(CodeModelState state, ProjectId projectId, SymbolKey namespaceSymbolId)
 {
     var newEnumerator = new ExternalNamespaceEnumerator(state, projectId, namespaceSymbolId);
     return (IEnumerator)ComAggregate.CreateAggregatedObject(newEnumerator);
 }
예제 #52
0
        private async Task <Location> RelocateSymbol_NoLock(MetadataAsSourceGeneratedFileInfo fileInfo, SymbolKey symbolId, CancellationToken cancellationToken)
        {
            Contract.ThrowIfNull(_workspace);

            // We need to relocate the symbol in the already existing file. If the file is open, we can just
            // reuse that workspace. Otherwise, we have to go spin up a temporary project to do the binding.
            if (_openedDocumentIds.TryGetValue(fileInfo, out var openDocumentId))
            {
                // Awesome, it's already open. Let's try to grab a document for it
                var document = _workspace.CurrentSolution.GetDocument(openDocumentId);

                return(await MetadataAsSourceHelpers.GetLocationInGeneratedSourceAsync(symbolId, document, cancellationToken).ConfigureAwait(false));
            }

            // Annoying case: the file is still on disk. Only real option here is to spin up a fake project to go and bind in.
            var temporaryProjectInfoAndDocumentId = fileInfo.GetProjectInfoAndDocumentId(_workspace, loadFileFromDisk: true);
            var temporaryDocument = _workspace.CurrentSolution.AddProject(temporaryProjectInfoAndDocumentId.Item1)
                                    .GetDocument(temporaryProjectInfoAndDocumentId.Item2);

            return(await MetadataAsSourceHelpers.GetLocationInGeneratedSourceAsync(symbolId, temporaryDocument, cancellationToken).ConfigureAwait(false));
        }
예제 #53
0
            public async Task <SymbolMappingResult?> MapSymbolAsync(Document document, ISymbol symbol, CancellationToken cancellationToken)
            {
                var compilation = await document.Project.GetCompilationAsync(cancellationToken).ConfigureAwait(false);

                return(await MapSymbolAsync(document, SymbolKey.Create(symbol, cancellationToken), cancellationToken).ConfigureAwait(false));
            }
 internal override bool Equals(SymbolKey other, ComparisonOptions options)
 {
     return ReferenceEquals(this, other);
 }
예제 #55
0
        private async Task <UniqueDocumentKey> GetUniqueDocumentKey(Project project, INamedTypeSymbol topLevelNamedType, bool allowDecompilation, CancellationToken cancellationToken)
        {
            var compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false);

            Contract.ThrowIfNull(compilation, "We are trying to produce a key for a language that doesn't support compilations.");

            var peMetadataReference = compilation.GetMetadataReference(topLevelNamedType.ContainingAssembly) as PortableExecutableReference;

            if (peMetadataReference?.FilePath != null)
            {
                return(new UniqueDocumentKey(peMetadataReference.FilePath, peMetadataReference.GetMetadataId(), project.Language, SymbolKey.Create(topLevelNamedType, cancellationToken), allowDecompilation));
            }
            else
            {
                var containingAssembly = topLevelNamedType.ContainingAssembly;
                return(new UniqueDocumentKey(containingAssembly.Identity, containingAssembly.GetMetadata()?.Id, project.Language, SymbolKey.Create(topLevelNamedType, cancellationToken), allowDecompilation));
            }
        }