Beispiel #1
0
        public async Task <IActionResult> FindImplementations([FromBody] Request request)
        {
            _workspace.EnsureBufferUpdated(request);

            var document = _workspace.GetDocument(request.FileName);
            var response = new QuickFixResponse();

            if (document != null)
            {
                var semanticModel = await document.GetSemanticModelAsync();

                var sourceText = await document.GetTextAsync();

                var position        = sourceText.Lines.GetPosition(new LinePosition(request.Line - 1, request.Column - 1));
                var symbol          = SymbolFinder.FindSymbolAtPosition(semanticModel, position, _workspace);
                var implementations = await SymbolFinder.FindImplementationsAsync(symbol, _workspace.CurrentSolution);

                var quickFixes = new List <QuickFix>();

                foreach (var implementation in implementations)
                {
                    foreach (var location in implementation.Locations)
                    {
                        AddQuickFix(quickFixes, location);
                    }
                }

                response = new QuickFixResponse(quickFixes.OrderBy(q => q.FileName)
                                                .ThenBy(q => q.Line)
                                                .ThenBy(q => q.Column));
            }

            return(new ObjectResult(response));
        }
Beispiel #2
0
        public async Task <QuickFixResponse> FindImplementations([FromBody] Request request)
        {
            _workspace.EnsureBufferUpdated(request);

            var document = _workspace.GetDocument(request.FileName);
            var response = new QuickFixResponse();

            if (document != null)
            {
                var semanticModel = await document.GetSemanticModelAsync();

                var sourceText = await document.GetTextAsync();

                var position   = sourceText.Lines.GetPosition(new LinePosition(request.Line - 1, request.Column - 1));
                var symbol     = SymbolFinder.FindSymbolAtPosition(semanticModel, position, _workspace);
                var quickFixes = new List <QuickFix>();

                var implementations = await SymbolFinder.FindImplementationsAsync(symbol, _workspace.CurrentSolution);
                await AddQuickFixes(quickFixes, implementations);

                var overrides = await SymbolFinder.FindOverridesAsync(symbol, _workspace.CurrentSolution);
                await AddQuickFixes(quickFixes, overrides);

                var derivedTypes = await GetDerivedTypes(symbol);
                await AddQuickFixes(quickFixes, derivedTypes);

                response = new QuickFixResponse(quickFixes.OrderBy(q => q.FileName)
                                                .ThenBy(q => q.Line)
                                                .ThenBy(q => q.Column));
            }

            return(response);
        }
        public static QuickFixResponse OnlyThisFile(this QuickFixResponse response, string fileName)
        {
            if (response?.QuickFixes == null)
            {
                return(response);
            }

            var quickFixes = response.QuickFixes.Where(x => PathsAreEqual(x.FileName, fileName));

            response.QuickFixes = quickFixes;
            return(response);

            bool PathsAreEqual(string x, string y)
            {
                if (x == null && y == null)
                {
                    return(true);
                }
                if (x == null || y == null)
                {
                    return(false);
                }

                var comparer = PlatformHelper.IsWindows ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal;

                return(Path.GetFullPath(x).Equals(Path.GetFullPath(y), comparer));
            }
        }
        public static QuickFixResponse OnlyThisFile(this QuickFixResponse response, string fileName)
        {
            if (response?.QuickFixes == null)
            {
                return(response);
            }

            var quickFixes = response.QuickFixes.Where(x => PathsAreEqual(x.FileName, fileName));

            response.QuickFixes = quickFixes;
            return(response);
        }
        public async Task <QuickFixResponse> FindUsages(FindUsagesRequest request)
        {
            var document = _workspace.GetDocument(request.FileName);
            var response = new QuickFixResponse();

            if (document != null)
            {
                var semanticModel = await document.GetSemanticModelAsync();

                var sourceText = await document.GetTextAsync();

                var position   = sourceText.Lines.GetPosition(new LinePosition(request.Line - 1, request.Column - 1));
                var symbol     = SymbolFinder.FindSymbolAtPosition(semanticModel, position, _workspace);
                var definition = await SymbolFinder.FindSourceDefinitionAsync(symbol, _workspace.CurrentSolution);

                var usages = request.OnlyThisFile
                    ? await SymbolFinder.FindReferencesAsync(definition ?? symbol, _workspace.CurrentSolution, ImmutableHashSet.Create(document))
                    : await SymbolFinder.FindReferencesAsync(definition ?? symbol, _workspace.CurrentSolution);

                var locations = new List <Location>();

                foreach (var usage in usages.Where(u => u.Definition.CanBeReferencedByName || (symbol as IMethodSymbol)?.MethodKind == MethodKind.Constructor))
                {
                    foreach (var location in usage.Locations)
                    {
                        locations.Add(location.Location);
                    }

                    if (!request.ExcludeDefinition)
                    {
                        var definitionLocations = usage.Definition.Locations
                                                  .Where(loc => loc.IsInSource && (!request.OnlyThisFile || loc.SourceTree.FilePath == request.FileName));

                        foreach (var location in definitionLocations)
                        {
                            locations.Add(location);
                        }
                    }
                }

                var quickFixTasks = locations.Select(async l => await GetQuickFix(l));

                var quickFixes = await Task.WhenAll(quickFixTasks);

                response = new QuickFixResponse(quickFixes.Distinct()
                                                .OrderBy(q => q.FileName)
                                                .ThenBy(q => q.Line)
                                                .ThenBy(q => q.Column));
            }

            return(response);
        }
        public static async Task <QuickFixResponse> TranslateAsync(this QuickFixResponse response, OmniSharpWorkspace workspace, Request request)
        {
            var quickFixes = new List <QuickFix>();

            foreach (var quickFix in response.QuickFixes)
            {
                await quickFix.TranslateAsync(workspace, request);

                if (quickFix.Line >= 0)
                {
                    quickFixes.Add(quickFix);
                }
            }

            response.QuickFixes = quickFixes;
            return(response);
        }
Beispiel #7
0
        public async Task <QuickFixResponse> FindUsages([FromBody] Request request)
        {
            _workspace.EnsureBufferUpdated(request);

            var document = _workspace.GetDocument(request.FileName);
            var response = new QuickFixResponse();

            if (document != null)
            {
                var semanticModel = await document.GetSemanticModelAsync();

                var sourceText = await document.GetTextAsync();

                var position   = sourceText.Lines.GetPosition(new LinePosition(request.Line - 1, request.Column - 1));
                var symbol     = SymbolFinder.FindSymbolAtPosition(semanticModel, position, _workspace);
                var definition = await SymbolFinder.FindSourceDefinitionAsync(symbol, _workspace.CurrentSolution);

                var usages = await SymbolFinder.FindReferencesAsync(definition ?? symbol, _workspace.CurrentSolution);

                var locations = new HashSet <Location>();

                foreach (var usage in usages.Where(u => u.Definition.CanBeReferencedByName || (symbol as IMethodSymbol)?.MethodKind == MethodKind.Constructor))
                {
                    foreach (var location in usage.Locations)
                    {
                        locations.Add(location.Location);
                    }

                    var definitionLocations = usage.Definition.Locations.Where(loc => loc.IsInSource);
                    foreach (var location in definitionLocations)
                    {
                        locations.Add(location);
                    }
                }
                var quickFixTasks = locations.Select(async l => await GetQuickFix(l));

                var quickFixes = await Task.WhenAll(quickFixTasks);

                response = new QuickFixResponse(quickFixes.OrderBy(q => q.FileName)
                                                .ThenBy(q => q.Line)
                                                .ThenBy(q => q.Column));
            }

            return(response);
        }
Beispiel #8
0
        public async Task LoadOnDemandProjectsOneByOne()
        {
            var configData = new Dictionary <string, string> {
                [$"MsBuild:{nameof(MSBuildOptions.LoadProjectsOnDemand)}"] = "true"
            };

            using (var testProject = await TestAssets.Instance.GetTestProjectAsync("TwoProjectsWithSolution"))
                using (var host = CreateMSBuildTestHost(testProject.Directory, configurationData: configData.ToConfiguration()))
                {
                    MSBuildWorkspaceInfo workspaceInfo = await host.RequestMSBuildWorkspaceInfoAsync();

                    // Expect empty workspace initially since no documents have been requested yet
                    Assert.Null(workspaceInfo.SolutionPath);
                    Assert.NotNull(workspaceInfo.Projects);
                    Assert.Equal(0, workspaceInfo.Projects.Count);

                    // Requesting library document should load only that project
                    GetCodeActionsService  codeActionHandler  = host.GetRequestHandler <GetCodeActionsService>(OmniSharpEndpoints.V2.GetCodeActions);
                    GetCodeActionsResponse codeActionResponse = await codeActionHandler.Handle(
                        new GetCodeActionsRequest { FileName = Path.Combine(testProject.Directory, "Lib", "Class1.cs") });

                    workspaceInfo = await host.RequestMSBuildWorkspaceInfoAsync();

                    Assert.NotNull(codeActionResponse);
                    Assert.Null(workspaceInfo.SolutionPath);
                    Assert.NotNull(workspaceInfo.Projects);
                    Assert.Equal(1, workspaceInfo.Projects.Count);
                    Assert.Equal("Lib.csproj", Path.GetFileName(workspaceInfo.Projects[0].Path));

                    // Requesting app document should load that project as well
                    QuickFixResponse codeCheckResponse = await host.RequestCodeCheckAsync(Path.Combine(testProject.Directory, "App", "Program.cs"));

                    workspaceInfo = await host.RequestMSBuildWorkspaceInfoAsync();

                    Assert.NotNull(codeCheckResponse);
                    Assert.Null(workspaceInfo.SolutionPath);
                    Assert.NotNull(workspaceInfo.Projects);
                    Assert.Equal(2, workspaceInfo.Projects.Count);
                    Assert.Equal("App.csproj", Path.GetFileName(workspaceInfo.Projects[0].Path));
                    Assert.Equal("Lib.csproj", Path.GetFileName(workspaceInfo.Projects[1].Path));
                }
        }
        public async Task <IActionResult> FindUsages([FromBody] Request request)
        {
            _workspace.EnsureBufferUpdated(request);

            var documentId = _workspace.GetDocumentId(request.FileName);
            var response   = new QuickFixResponse();

            if (documentId != null)
            {
                var document      = _workspace.CurrentSolution.GetDocument(documentId);
                var semanticModel = await document.GetSemanticModelAsync();

                var sourceText = await document.GetTextAsync();

                var position   = sourceText.Lines.GetPosition(new LinePosition(request.Line - 1, request.Column));
                var symbol     = SymbolFinder.FindSymbolAtPosition(semanticModel, position, _workspace);
                var definition = await SymbolFinder.FindSourceDefinitionAsync(symbol, _workspace.CurrentSolution);

                var usages = await SymbolFinder.FindReferencesAsync(definition, _workspace.CurrentSolution);

                var quickFixes = new List <QuickFix>();

                foreach (var usage in usages)
                {
                    foreach (var location in usage.Locations)
                    {
                        quickFixes.Add(GetQuickFix(location.Location));
                    }

                    foreach (var location in usage.Definition.Locations)
                    {
                        quickFixes.Add(GetQuickFix(location));
                    }
                }

                response = new QuickFixResponse(quickFixes);
            }

            return(new ObjectResult(response));
        }
        public static async Task <QuickFixResponse> TranslateAsync(this QuickFixResponse response, OmniSharpWorkspace workspace, Request request, bool removeGenerated = false)
        {
            var quickFixes = new List <QuickFix>();

            foreach (var quickFix in response.QuickFixes)
            {
                await quickFix.TranslateAsync(workspace, request);

                if (quickFix.Line < 0)
                {
                    continue;
                }
                if (removeGenerated && quickFix.FileName.Equals(Constants.Paths.Generated))
                {
                    continue;
                }
                quickFixes.Add(quickFix);
            }

            response.QuickFixes = quickFixes;
            return(response);
        }
Beispiel #11
0
        public async Task TestProjectWithSignedReferencedProject()
        {
            using (ITestProject testProject = await TestAssets.Instance.GetTestProjectAsync("SolutionWithSignedProject"))
                using (OmniSharpTestHost host = CreateOmniSharpHost(Path.Combine(testProject.Directory)))
                {
                    MSBuildWorkspaceInfo workspaceInfo = await GetWorkspaceInfoAsync(host);

                    Assert.NotNull(workspaceInfo.Projects);
                    Assert.Equal(2, workspaceInfo.Projects.Count);

                    // For the test to validate that assemblies representing targets of loaded projects are being skipped,
                    // the assemblies must be present on disk.
                    foreach (MSBuildProjectInfo loadedProject in workspaceInfo.Projects)
                    {
                        Assert.True(File.Exists(loadedProject.TargetPath),
                                    $"Project target assembly is not found {loadedProject.TargetPath}. " +
                                    $"Make sure to build the whole repo using the build script before running the test.");
                    }

                    // The callee assembly must be signed to ensure that in case of a bug the assembly is loaded
                    // "The type 'Callee' exists in both ..." is present as a code check (which is validated below).
                    MSBuildProjectInfo signedProject = workspaceInfo.Projects.SingleOrDefault(p => p.AssemblyName.Equals("CalleeLib", StringComparison.OrdinalIgnoreCase));
                    Assert.NotNull(signedProject);
                    string token = BitConverter.ToString(AssemblyName.GetAssemblyName(signedProject.TargetPath).GetPublicKeyToken());
                    Assert.Equal("A5-D8-5A-5B-AA-39-A6-A6", token, ignoreCase: true);

                    QuickFixResponse quickFixResponse = await GetCodeChecksync(host, Path.Combine(testProject.Directory, "CallerLib\\Caller.cs"));

                    // Log result to easier debugging of the test should it fail during automated valdiation
                    foreach (QuickFix fix in quickFixResponse.QuickFixes)
                    {
                        host.Logger.LogInformation($"Unexpected QuickFix returned for {fix.FileName}: {fix.Text}");
                    }

                    Assert.Empty(quickFixResponse.QuickFixes);
                }
        }
Beispiel #12
0
        public QuickFixResponse FindUsages(FindUsagesRequest request)
        {
            var result = FindUsageNodes(request)
                         .Distinct(new NodeComparer())
                         .OrderBy(n => n.GetRegion().FileName.FixPath())
                         .ThenBy(n => n.StartLocation.Line)
                         .ThenBy(n => n.StartLocation.Column);

            var res = new QuickFixResponse();

            if (result.Any())
            {
                var usages = result.Select(node => new QuickFix
                {
                    FileName = node.GetRegion().FileName,
                    Text     = node.Preview(_solution.GetFile(node.GetRegion().FileName), request.MaxWidth).Replace("'", "''"),
                    Line     = node.StartLocation.Line,
                    Column   = node.StartLocation.Column,
                });
                res.QuickFixes = usages;
            }

            return(res);
        }
 public static Task <QuickFixResponse> TranslateAsync(this QuickFixResponse response, OmniSharpWorkspace workspace)
 {
     return(response.TranslateAsync(workspace, new Request()));
 }