예제 #1
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);
        }
        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();
            }

            if (namespaceSymbolId.Resolve(project.GetCompilationAsync().Result).Symbol is not INamespaceSymbol namespaceSymbol)
            {
                throw Exceptions.ThrowEFail();
            }

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

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

                    if (namedType.IsAccessibleWithin(containingAssembly))
                    {
                        if (namedType.Locations.Any(static l => l.IsInMetadata || l.IsInSource))
예제 #3
0
        public async Task <SymbolAndProjectId?> TryRehydrateAsync(
            Solution solution, CancellationToken cancellationToken)
        {
            var projectId   = ProjectId;
            var project     = solution.GetProject(projectId);
            var compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false);

            // The server and client should both be talking about the same compilation.  As such
            // locations in symbols are save to resolve as we rehydrate the SymbolKey.
            var symbol = SymbolKey.Resolve(
                SymbolKeyData, compilation, resolveLocations: true, cancellationToken: cancellationToken).GetAnySymbol();

            if (symbol == null)
            {
                try
                {
                    throw new InvalidOperationException(
                              $"We should always be able to resolve a symbol back on the host side:\r\n{SymbolKeyData}");
                }
                catch (Exception ex) when(FatalError.ReportWithoutCrash(ex))
                {
                    return(null);
                }
            }

            return(new SymbolAndProjectId(symbol, projectId));
        }
예제 #4
0
        private ImmutableArray <EnvDTE.CodeElement> GetChildren()
        {
            if (_children == null)
            {
                var project = this.State.Workspace.CurrentSolution.GetProject(_projectId);
                if (project == null)
                {
                    throw Exceptions.ThrowEFail();
                }

                var typeSymbol = _typeSymbolId.Resolve(project.GetCompilationAsync().Result).Symbol as ITypeSymbol;
                if (typeSymbol == null)
                {
                    throw Exceptions.ThrowEFail();
                }

                var childrenBuilder = ImmutableArray.CreateBuilder <EnvDTE.CodeElement>();

                foreach (var member in typeSymbol.GetMembers())
                {
                    childrenBuilder.Add(this.State.CodeModelService.CreateExternalCodeElement(this.State, _projectId, member));
                }

                foreach (var typeMember in typeSymbol.GetTypeMembers())
                {
                    childrenBuilder.Add(this.State.CodeModelService.CreateExternalCodeElement(this.State, _projectId, typeMember));
                }

                _children = childrenBuilder.ToImmutable();
            }

            return(_children);
        }
        private static async Task <bool> HasInternalsAccessAsync(
            IAssemblySymbol sourceAssembly, Lazy <HashSet <string> > internalsVisibleToMap,
            SymbolKey sourceAssemblySymbolKey, Project project, CancellationToken cancellationToken)
        {
            if (internalsVisibleToMap.Value.Contains(project.AssemblyName) &&
                project.SupportsCompilation)
            {
                var compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false);

                var targetAssembly = compilation.Assembly;
                if (sourceAssembly.Language != targetAssembly.Language)
                {
                    var resolvedSymbol = sourceAssemblySymbolKey.Resolve(compilation, cancellationToken: cancellationToken).Symbol;
                    if (resolvedSymbol is IAssemblySymbol sourceAssemblyInTargetCompilation)
                    {
                        return(targetAssembly.IsSameAssemblyOrHasFriendAccessTo(sourceAssemblyInTargetCompilation));
                    }
                }
                else
                {
                    return(targetAssembly.IsSameAssemblyOrHasFriendAccessTo(sourceAssembly));
                }
            }

            return(false);
        }
예제 #6
0
        internal async Task <SymbolMappingResult> MapSymbolAsync(Document document, SymbolKey symbolId, CancellationToken cancellationToken)
        {
            MetadataAsSourceGeneratedFileInfo fileInfo;

            using (await _gate.DisposableWaitAsync(cancellationToken).ConfigureAwait(false))
            {
                if (!_openedDocumentIds.TryGetKey(document.Id, out fileInfo))
                {
                    return(null);
                }
            }

            // WARANING: do not touch any state fields outside the lock.
            var solution = fileInfo.Workspace.CurrentSolution;
            var project  = solution.GetProject(fileInfo.SourceProjectId);

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

            var compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false);

            var resolutionResult = symbolId.Resolve(compilation, ignoreAssemblyKey: true, cancellationToken: cancellationToken);

            if (resolutionResult.Symbol == null)
            {
                return(null);
            }

            return(new SymbolMappingResult(project, resolutionResult.Symbol));
        }
예제 #7
0
            private (Project project, ISymbol symbol) TryResolveSymbolInCurrentSolution(
                Workspace workspace, string symbolKey)
            {
                if (!this.Properties.TryGetValue(MetadataAssemblyIdentityDisplayName, out var identityDisplayName) ||
                    !AssemblyIdentity.TryParseDisplayName(identityDisplayName, out var identity))
                {
                    return(null, null);
                }

                var project = workspace.CurrentSolution
                              .ProjectsWithReferenceToAssembly(identity)
                              .FirstOrDefault();

                if (project == null)
                {
                    return(null, null);
                }

                var compilation = project.GetCompilationAsync(CancellationToken.None)
                                  .WaitAndGetResult(CancellationToken.None);

                var symbol = SymbolKey.Resolve(symbolKey, compilation).Symbol;

                return(project, symbol);
            }
예제 #8
0
        public static async Task <Location> GetLocationInGeneratedSourceAsync(
            SymbolKey symbolId,
            Document generatedDocument,
            CancellationToken cancellationToken
            )
        {
            var resolution = symbolId.Resolve(
                await generatedDocument.Project
                .GetCompilationAsync(cancellationToken)
                .ConfigureAwait(false),
                ignoreAssemblyKey: true,
                cancellationToken: cancellationToken
                );

            var location = GetFirstSourceLocation(resolution);

            if (location == null)
            {
                // If we cannot find the location of the  symbol.  Just 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);
        }
예제 #9
0
        public void TestTupleWithLocalTypeReferences2()
        {
            var source = @"
using System.Linq;

class C
{
    void Method((C a, int b) t)
    {
    }
}";
            // Tuples store locations along with them.  But we can only recover those locations
            // if we're re-resolving into a compilation with the same files.
            var compilation1 = GetCompilation(source, LanguageNames.CSharp, "File1.cs");
            var compilation2 = GetCompilation(source, LanguageNames.CSharp, "File2.cs");

            var symbol = GetAllSymbols(
                compilation1.GetSemanticModel(compilation1.SyntaxTrees.Single()),
                n => n is CSharp.Syntax.MethodDeclarationSyntax).Single();

            // Ensure we don't crash getting these symbol keys.
            var id = SymbolKey.ToString(symbol);
            Assert.NotNull(id);

            // Validate that if the client does ask to resolve locations that we
            // do not crash if those locations cannot be found.
            var found = SymbolKey.Resolve(id, compilation2, resolveLocations: true).GetAnySymbol();
            Assert.NotNull(found);

            Assert.Equal(symbol.Name, found.Name);
            Assert.Equal(symbol.Kind, found.Kind);

            var method = found as IMethodSymbol;
            Assert.True(method.Parameters[0].Type.IsTupleType);
        }
예제 #10
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);
        }
예제 #11
0
            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;
            }
예제 #12
0
        public async Task <SymbolAndProjectId> RehydrateAsync(
            Solution solution, CancellationToken cancellationToken)
        {
            var projectId   = ProjectId.Rehydrate();
            var project     = solution.GetProject(projectId);
            var compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false);

            var symbol = SymbolKey.Resolve(SymbolKeyData, compilation, cancellationToken: cancellationToken).GetAnySymbol();

            Debug.Assert(symbol != null, "We should always be able to resolve a symbol back on the host side.");
            return(new SymbolAndProjectId(symbol, projectId));
        }
예제 #13
0
        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);
        }
예제 #14
0
        public async Task <IReadOnlyCollection <object> > CreateDescriptionAsync(CancellationToken cancellationToken)
        {
            var document           = _textView.TextBuffer.CurrentSnapshot.GetOpenDocumentInCurrentContextWithChanges();
            var textContentBuilder = new List <TaggedText>();

            if (document != null)
            {
                var compilation = await document.Project.GetRequiredCompilationAsync(cancellationToken).ConfigureAwait(false);

                var symbol = _key.Resolve(compilation, cancellationToken: cancellationToken).Symbol;

                if (symbol != null)
                {
                    var workspace     = document.Project.Solution.Workspace;
                    var semanticModel = await document.GetRequiredSemanticModelAsync(cancellationToken).ConfigureAwait(false);

                    var symbolDisplayService = document.Project.LanguageServices.GetRequiredService <ISymbolDisplayService>();
                    var formatter            = document.Project.LanguageServices.GetService <IDocumentationCommentFormattingService>();
                    var sections             = await symbolDisplayService.ToDescriptionGroupsAsync(workspace, semanticModel, _span.Start, ImmutableArray.Create(symbol), cancellationToken).ConfigureAwait(false);

                    textContentBuilder.AddRange(sections[SymbolDescriptionGroups.MainDescription]);
                    if (formatter != null)
                    {
                        var documentation = symbol.GetDocumentationParts(semanticModel, _span.Start, formatter, cancellationToken);

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

                    if (sections.TryGetValue(SymbolDescriptionGroups.AnonymousTypes, out var parts))
                    {
                        if (!parts.IsDefaultOrEmpty)
                        {
                            textContentBuilder.AddLineBreak();
                            textContentBuilder.AddLineBreak();
                            textContentBuilder.AddRange(parts);
                        }
                    }
                }

                var uiCollection = Implementation.IntelliSense.Helpers.BuildInteractiveTextElements(textContentBuilder.ToImmutableArray <TaggedText>(),
                                                                                                    document, _threadingContext, _streamingPresenter);
                return(uiCollection);
            }

            return(Array.Empty <object>());
        }
예제 #15
0
        private static async Task AddNonSubmissionDependentProjectsAsync(IAssemblySymbol sourceAssembly, Solution solution, Project sourceProject, HashSet <DependentProject> dependentProjects, CancellationToken cancellationToken)
        {
            var isSubmission = sourceProject != null && sourceProject.IsSubmission;

            if (isSubmission)
            {
                return;
            }

            var internalsVisibleToMap = CreateInternalsVisibleToMap(sourceAssembly);

            SymbolKey sourceAssemblySymbolKey = null;

            // TODO(cyrusn): What about error tolerance situations.  Do we maybe want to search
            // transitive dependencies as well?  Even if the code wouldn't compile, they may be
            // things we want to find.
            foreach (var projectId in solution.ProjectIds)
            {
                var project = solution.GetProject(projectId);

                cancellationToken.ThrowIfCancellationRequested();

                if (HasReferenceTo(sourceAssembly, sourceProject, project, cancellationToken))
                {
                    bool hasInternalsAccess = false;
                    if (internalsVisibleToMap.Value.Contains(project.AssemblyName))
                    {
                        var compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false);

                        var targetAssembly = compilation.Assembly;
                        if (sourceAssembly.Language != targetAssembly.Language)
                        {
                            sourceAssemblySymbolKey = sourceAssemblySymbolKey ?? sourceAssembly.GetSymbolKey();
                            var sourceAssemblyInTargetCompilation = sourceAssemblySymbolKey.Resolve(compilation, cancellationToken: cancellationToken).Symbol as IAssemblySymbol;

                            if (sourceAssemblyInTargetCompilation != null)
                            {
                                hasInternalsAccess = targetAssembly.IsSameAssemblyOrHasFriendAccessTo(sourceAssemblyInTargetCompilation);
                            }
                        }
                        else
                        {
                            hasInternalsAccess = targetAssembly.IsSameAssemblyOrHasFriendAccessTo(sourceAssembly);
                        }
                    }

                    dependentProjects.Add(new DependentProject(project.Id, hasInternalsAccess));
                }
            }
        }
예제 #16
0
        public async Task <SymbolAndProjectId> RehydrateAsync(
            Solution solution, CancellationToken cancellationToken)
        {
            var projectId   = ProjectId;
            var project     = solution.GetProject(projectId);
            var compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false);

            // The server and client should both be talking about the same compilation.  As such
            // locations in symbols are save to resolve as we rehydrate the SymbolKey.
            var symbol = SymbolKey.Resolve(
                SymbolKeyData, compilation, resolveLocations: true, cancellationToken: cancellationToken).GetAnySymbol();

            Debug.Assert(symbol != null, "We should always be able to resolve a symbol back on the host side.");
            return(new SymbolAndProjectId(symbol, projectId));
        }
예제 #17
0
        public override int GoToSource()
        {
            var resolution         = _symbolKey.Resolve(_workspace.CurrentSolution.GetCompilationAsync(_referencingProjectId, CancellationToken.None).Result);
            var referencingProject = _workspace.CurrentSolution.GetProject(_referencingProjectId);

            if (resolution.Symbol != null && referencingProject != null)
            {
                var navigationService = _workspace.Services.GetService <ISymbolNavigationService>();
                return(navigationService.TryNavigateToSymbol(resolution.Symbol, referencingProject)
                    ? VSConstants.S_OK
                    : VSConstants.E_FAIL);
            }

            return(VSConstants.E_FAIL);
        }
예제 #18
0
        public async Task NavigateToAsync(SymbolKey id, Project project, CancellationToken cancellationToken)
        {
            var compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false);

            var resolution = id.Resolve(compilation, cancellationToken: cancellationToken);
            var workspace  = project.Solution.Workspace;
            var options    = NavigationOptions.Default with {
                PreferProvisionalTab = true
            };
            var symbolNavigationService = workspace.Services.GetService <ISymbolNavigationService>();

            await symbolNavigationService.TryNavigateToSymbolAsync(
                resolution.Symbol, project, options, cancellationToken).ConfigureAwait(false);
        }
    }
예제 #19
0
            private ValueTuple <Project, ISymbol>?ResolveSymbolInCurrentSolution()
            {
                var project = _workspace.CurrentSolution
                              .ProjectsWithReferenceToAssembly(_symbolAssemblyIdentity)
                              .FirstOrDefault();

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

                var compilation = project.GetCompilationAsync(CancellationToken.None)
                                  .WaitAndGetResult(CancellationToken.None);

                return(ValueTuple.Create(project, _symbolKey.Resolve(compilation).Symbol));
            }
예제 #20
0
        public async Task <ValueTrackedItem?> RehydrateAsync(Solution solution, CancellationToken cancellationToken)
        {
            var document      = solution.GetRequiredDocument(DocumentId);
            var semanticModel = await document.GetRequiredSemanticModelAsync(cancellationToken).ConfigureAwait(false);

            var symbolResolution = SymbolKey.Resolve(semanticModel.Compilation, cancellationToken: cancellationToken);

            if (symbolResolution.Symbol is null)
            {
                return(null);
            }

            cancellationToken.ThrowIfCancellationRequested();
            var parent = Parent is null ? null : await Parent.RehydrateAsync(solution, cancellationToken).ConfigureAwait(false);

            return(await ValueTrackedItem.TryCreateAsync(document, TextSpan, symbolResolution.Symbol, parent, cancellationToken).ConfigureAwait(false));
        }
        public async ValueTask <ValueTrackedItem> RehydrateAsync(Solution solution, CancellationToken cancellationToken)
        {
            var document      = solution.GetRequiredDocument(DocumentId);
            var semanticModel = await document.GetRequiredSemanticModelAsync(cancellationToken).ConfigureAwait(false);

            var symbolResolution = SymbolKey.Resolve(semanticModel.Compilation, cancellationToken: cancellationToken);

            Contract.ThrowIfNull(symbolResolution.Symbol);

            cancellationToken.ThrowIfCancellationRequested();
            var parent = Parent is null ? null : await Parent.RehydrateAsync(solution, cancellationToken).ConfigureAwait(false);

            var syntaxTree = await document.GetRequiredSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);

            var sourceText = await syntaxTree.GetTextAsync(cancellationToken).ConfigureAwait(false);

            return(new ValueTrackedItem(SymbolKey, sourceText, TextSpan, DocumentId, symbolResolution.Symbol.GetGlyph(), parent));
        }
예제 #22
0
        private void TestRoundTrip(ISymbol symbol, Compilation compilation, Func<ISymbol, object> fnId = null)
        {
            var id = SymbolKey.ToString(symbol);
            Assert.NotNull(id);
            var found = SymbolKey.Resolve(id, compilation).GetAnySymbol();
            Assert.NotNull(found);

            if (fnId != null)
            {
                var expected = fnId(symbol);
                var actual = fnId(found);
                Assert.Equal(expected, actual);
            }
            else
            {
                Assert.Equal(symbol, found);
            }
        }
예제 #23
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;
        }
예제 #24
0
        private async Task SearchAsync(ICallHierarchySearchCallback callback, CallHierarchySearchScope scope, CancellationToken cancellationToken)
        {
            callback.ReportProgress(0, 1);

            var asyncToken = _asyncListener.BeginAsyncOperation(this.GetType().Name + ".Search");

            // Follow the search task with task that lets the callback know we're done and which
            // marks the async operation as complete.  Note that we pass CancellationToken.None
            // here.  That's intentional.  This operation is *not* cancellable.

            var workspace      = _project.Solution.Workspace;
            var currentProject = workspace.CurrentSolution.GetProject(_project.Id);
            var compilation    = await currentProject.GetCompilationAsync(cancellationToken).ConfigureAwait(false);

            var resolution = _symbol.Resolve(compilation, cancellationToken: cancellationToken);

            var documents = this.Documents ?? IncludeDocuments(scope, currentProject);

            var currentSymbol = resolution.Symbol;

            if (currentSymbol == null)
            {
                return;
            }

            await SearchWorkerAsync(currentSymbol, currentProject, callback, documents, cancellationToken).SafeContinueWith(
                t =>
            {
                callback.ReportProgress(1, 1);

                if (t.Status == TaskStatus.RanToCompletion)
                {
                    callback.SearchSucceeded();
                }
                else
                {
                    callback.SearchFailed(EditorFeaturesResources.Canceled);
                }

                asyncToken.Dispose();
            }, CancellationToken.None, TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default).ConfigureAwait(false);
        }
        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);
        }
예제 #26
0
        private static async Task <ImmutableArray <TaggedText> > GetDescriptionAsync(Document document, int position, SymbolKey symbolKey, CancellationToken cancellationToken)
        {
            var semanticModel = await document.GetRequiredSemanticModelAsync(cancellationToken).ConfigureAwait(false);

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

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

                var parts = new List <TaggedText>();

                var groups = await symbolDisplayService.ToDescriptionGroupsAsync(
                    workspace, semanticModel, position, ImmutableArray.Create(symbol), 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.AnonymousTypes, out var anonymousTypes))
                {
                    if (!anonymousTypes.IsDefaultOrEmpty)
                    {
                        parts.AddLineBreak();
                        parts.AddLineBreak();
                        parts.AddRange(anonymousTypes);
                    }
                }

                return(parts.ToImmutableArray());
            }

            return(default);
예제 #27
0
        public void TestConstructedMethodInsideLocalFunctionWithTypeParameters()
        {
            var source      = @"
using System.Linq;

class C
{
    void Method()
    {
        object LocalFunction<T>()
        {
            return Enumerable.Empty<T>();
        }
    }
}";
            var compilation = GetCompilation(source, LanguageNames.CSharp);
            var symbols     = GetAllSymbols(
                compilation.GetSemanticModel(compilation.SyntaxTrees.Single()),
                n => n is CSharp.Syntax.MemberAccessExpressionSyntax || n is CSharp.Syntax.InvocationExpressionSyntax);

            var tested = false;

            foreach (var symbol in symbols)
            {
                // Ensure we don't crash getting these symbol keys.
                var id = SymbolKey.ToString(symbol);
                Assert.NotNull(id);
                var found = SymbolKey.Resolve(id, compilation: compilation).GetAnySymbol();
                Assert.NotNull(found);

                // note: we don't check that the symbols are equal.  That's because the compiler
                // doesn't guarantee that the TypeParameters will be hte same across successive
                // invocations.
                Assert.Equal(symbol.OriginalDefinition, found.OriginalDefinition);

                tested = true;
            }

            Assert.True(tested);
        }
        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.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);
                }
            }
        }
예제 #29
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.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);
                }
            }
        }
            private (Project project, ISymbol symbol) TryResolveSymbolInCurrentSolution(
                Workspace workspace, string symbolKey)
            {
                if (!this.Properties.TryGetValue(MetadataSymbolOriginatingProjectIdGuid, out var projectIdGuid) ||
                    !this.Properties.TryGetValue(MetadataSymbolOriginatingProjectIdDebugName, out var projectDebugName))
                {
                    return(null, null);
                }

                var project = workspace.CurrentSolution.GetProject(ProjectId.CreateFromSerialized(Guid.Parse(projectIdGuid), projectDebugName));

                if (project == null)
                {
                    return(null, null);
                }

                var compilation = project.GetCompilationAsync(CancellationToken.None)
                                  .WaitAndGetResult(CancellationToken.None);

                var symbol = SymbolKey.Resolve(symbolKey, compilation).Symbol;

                return(project, symbol);
            }
예제 #31
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);
                        }
                    }
                }
            }
        }
예제 #32
0
        private async Task SearchAsync(Workspace workspace, CallHierarchySearchScope scope, ICallHierarchySearchCallback callback, CancellationToken cancellationToken)
        {
            var project = workspace.CurrentSolution.GetProject(_projectId);

            if (project == null)
            {
                throw new Exception(string.Format(WorkspacesResources.The_symbol_0_cannot_be_located_within_the_current_solution, SymbolName));
            }

            var compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false);

            var resolution = _symbolKey.Resolve(compilation, cancellationToken: cancellationToken);

            var symbol = resolution.Symbol;

            if (symbol == null)
            {
                throw new Exception(string.Format(WorkspacesResources.The_symbol_0_cannot_be_located_within_the_current_solution, SymbolName));
            }

            var documents = this.Documents ?? IncludeDocuments(scope, project);

            await SearchWorkerAsync(symbol, project, callback, documents, cancellationToken).ConfigureAwait(false);
        }
예제 #33
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);
        }
예제 #34
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);
 }
예제 #35
0
 private static ISymbol DecodeSymbol(string id, Compilation compilation)
 {
     return(SymbolKey.Resolve(id, compilation).GetAnySymbol());
 }
예제 #36
0
 public ISymbol ResolveSymbol(Compilation compilation)
 {
     return(_symbolKey.Resolve(compilation, ignoreAssemblyKey: false).Symbol);
 }