diff --git a/src/Features/Lsif/Generator/Generator.cs b/src/Features/Lsif/Generator/Generator.cs index 1d27784cb7b7f..0e094db7bf6ca 100644 --- a/src/Features/Lsif/Generator/Generator.cs +++ b/src/Features/Lsif/Generator/Generator.cs @@ -22,14 +22,34 @@ namespace Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator { internal sealed class Generator { + // LSIF generator capabilities. See https://github.com/microsoft/lsif-node/blob/main/protocol/src/protocol.ts#L925 for details. + private const bool HoverProvider = true; + private const bool DeclarationProvider = false; + private const bool DefinitionProvider = true; + private const bool ReferencesProvider = true; + private const bool TypeDefinitionProvider = false; + private const bool DocumentSymbolProvider = false; + private const bool FoldingRangeProvider = true; + private const bool DiagnosticProvider = false; + private readonly ILsifJsonWriter _lsifJsonWriter; private readonly IdFactory _idFactory = new IdFactory(); - public Generator(ILsifJsonWriter lsifJsonWriter) + private Generator(ILsifJsonWriter lsifJsonWriter) { _lsifJsonWriter = lsifJsonWriter; } + public static Generator CreateAndWriteCapabilitiesVertex(ILsifJsonWriter lsifJsonWriter) + { + var generator = new Generator(lsifJsonWriter); + var capabilitiesVertex = new Capabilities(generator._idFactory, + HoverProvider, DeclarationProvider, DefinitionProvider, ReferencesProvider, + TypeDefinitionProvider, DocumentSymbolProvider, FoldingRangeProvider, DiagnosticProvider); + generator._lsifJsonWriter.Write(capabilitiesVertex); + return generator; + } + public void GenerateForCompilation(Compilation compilation, string projectPath, HostLanguageServices languageServices, OptionSet options) { var projectVertex = new Graph.LsifProject(kind: GetLanguageKind(compilation.Language), new Uri(projectPath), _idFactory); diff --git a/src/Features/Lsif/Generator/Graph/Capabilities.cs b/src/Features/Lsif/Generator/Graph/Capabilities.cs new file mode 100644 index 0000000000000..ce8568aa73e39 --- /dev/null +++ b/src/Features/Lsif/Generator/Graph/Capabilities.cs @@ -0,0 +1,60 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Newtonsoft.Json; + +namespace Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.Graph +{ + /// + /// Represents a single Capabilities vertex for serialization. See https://github.com/microsoft/lsif-node/blob/main/protocol/src/protocol.ts#L973 for further details. + /// + internal sealed class Capabilities : Vertex + { + [JsonProperty("hoverProvider")] + public bool HoverProvider { get; } + + [JsonProperty("declarationProvider")] + public bool DeclarationProvider { get; } + + [JsonProperty("definitionProvider")] + public bool DefinitionProvider { get; } + + [JsonProperty("referencesProvider")] + public bool ReferencesProvider { get; } + + [JsonProperty("typeDefinitionProvider")] + public bool TypeDefinitionProvider { get; } + + [JsonProperty("documentSymbolProvider")] + public bool DocumentSymbolProvider { get; } + + [JsonProperty("foldingRangeProvider")] + public bool FoldingRangeProvider { get; } + + [JsonProperty("diagnosticProvider")] + public bool DiagnosticProvider { get; } + + public Capabilities( + IdFactory idFactory, + bool hoverProvider, + bool declarationProvider, + bool definitionProvider, + bool referencesProvider, + bool typeDefinitionProvider, + bool documentSymbolProvider, + bool foldingRangeProvider, + bool diagnosticProvider) + : base(label: "capabilities", idFactory) + { + HoverProvider = hoverProvider; + DeclarationProvider = declarationProvider; + DefinitionProvider = definitionProvider; + ReferencesProvider = referencesProvider; + TypeDefinitionProvider = typeDefinitionProvider; + DocumentSymbolProvider = documentSymbolProvider; + FoldingRangeProvider = foldingRangeProvider; + DiagnosticProvider = diagnosticProvider; + } + } +} diff --git a/src/Features/Lsif/Generator/Program.cs b/src/Features/Lsif/Generator/Program.cs index 2e07c00106ed6..119b1ba7e21ae 100644 --- a/src/Features/Lsif/Generator/Program.cs +++ b/src/Features/Lsif/Generator/Program.cs @@ -136,7 +136,7 @@ private static async Task GenerateWithMSBuildLocatedAsync( var solution = await openAsync(msbuildWorkspace); await logFile.WriteLineAsync($"Load completed in {solutionLoadStopwatch.Elapsed.ToDisplayString()}."); - var lsifGenerator = new Generator(lsifWriter); + var lsifGenerator = Generator.CreateAndWriteCapabilitiesVertex(lsifWriter); var totalTimeInGenerationAndCompilationFetchStopwatch = Stopwatch.StartNew(); var totalTimeInGenerationPhase = TimeSpan.Zero; @@ -173,7 +173,7 @@ private static async Task GenerateFromCompilerInvocationAsync(FileInfo compilerI await logFile.WriteLineAsync($"Load of the project completed in {compilerInvocationLoadStopwatch.Elapsed.ToDisplayString()}."); var generationStopwatch = Stopwatch.StartNew(); - var lsifGenerator = new Generator(lsifWriter); + var lsifGenerator = Generator.CreateAndWriteCapabilitiesVertex(lsifWriter); lsifGenerator.GenerateForCompilation(compilerInvocation.Compilation, compilerInvocation.ProjectFilePath, compilerInvocation.LanguageServices, compilerInvocation.Options); await logFile.WriteLineAsync($"Generation for {compilerInvocation.ProjectFilePath} completed in {generationStopwatch.Elapsed.ToDisplayString()}."); diff --git a/src/Features/Lsif/GeneratorTest/OutputFormatTests.vb b/src/Features/Lsif/GeneratorTest/OutputFormatTests.vb index c03e713c7fceb..2ba3059feca06 100644 --- a/src/Features/Lsif/GeneratorTest/OutputFormatTests.vb +++ b/src/Features/Lsif/GeneratorTest/OutputFormatTests.vb @@ -25,16 +25,17 @@ Namespace Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.UnitTests ), jsonWriter) AssertEx.EqualOrDiff( -"{""kind"":""csharp"",""resource"":""file:///Z:/TestProject.csproj"",""id"":1,""type"":""vertex"",""label"":""project""} -{""kind"":""begin"",""scope"":""project"",""data"":1,""id"":2,""type"":""vertex"",""label"":""$event""} -{""uri"":""file:///Z:/A.cs"",""languageId"":""csharp"",""id"":3,""type"":""vertex"",""label"":""document""} -{""kind"":""begin"",""scope"":""document"",""data"":3,""id"":4,""type"":""vertex"",""label"":""$event""} -{""outV"":3,""inVs"":[],""id"":5,""type"":""edge"",""label"":""contains""} -{""result"":[],""id"":6,""type"":""vertex"",""label"":""foldingRangeResult""} -{""outV"":3,""inVs"":[6],""id"":7,""type"":""edge"",""label"":""textDocument/foldingRange""} -{""kind"":""end"",""scope"":""document"",""data"":3,""id"":8,""type"":""vertex"",""label"":""$event""} -{""outV"":1,""inVs"":[3],""id"":9,""type"":""edge"",""label"":""contains""} -{""kind"":""end"",""scope"":""project"",""data"":1,""id"":10,""type"":""vertex"",""label"":""$event""} +"{""hoverProvider"":true,""declarationProvider"":false,""definitionProvider"":true,""referencesProvider"":true,""typeDefinitionProvider"":false,""documentSymbolProvider"":false,""foldingRangeProvider"":true,""diagnosticProvider"":false,""id"":1,""type"":""vertex"",""label"":""capabilities""} +{""kind"":""csharp"",""resource"":""file:///Z:/TestProject.csproj"",""id"":2,""type"":""vertex"",""label"":""project""} +{""kind"":""begin"",""scope"":""project"",""data"":2,""id"":3,""type"":""vertex"",""label"":""$event""} +{""uri"":""file:///Z:/A.cs"",""languageId"":""csharp"",""id"":4,""type"":""vertex"",""label"":""document""} +{""kind"":""begin"",""scope"":""document"",""data"":4,""id"":5,""type"":""vertex"",""label"":""$event""} +{""outV"":4,""inVs"":[],""id"":6,""type"":""edge"",""label"":""contains""} +{""result"":[],""id"":7,""type"":""vertex"",""label"":""foldingRangeResult""} +{""outV"":4,""inVs"":[7],""id"":8,""type"":""edge"",""label"":""textDocument/foldingRange""} +{""kind"":""end"",""scope"":""document"",""data"":4,""id"":9,""type"":""vertex"",""label"":""$event""} +{""outV"":2,""inVs"":[4],""id"":10,""type"":""edge"",""label"":""contains""} +{""kind"":""end"",""scope"":""project"",""data"":2,""id"":11,""type"":""vertex"",""label"":""$event""} ", stringWriter.ToString()) End Function @@ -54,80 +55,93 @@ Namespace Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.UnitTests AssertEx.EqualOrDiff( "[ + { + ""hoverProvider"": true, + ""declarationProvider"": false, + ""definitionProvider"": true, + ""referencesProvider"": true, + ""typeDefinitionProvider"": false, + ""documentSymbolProvider"": false, + ""foldingRangeProvider"": true, + ""diagnosticProvider"": false, + ""id"": 1, + ""type"": ""vertex"", + ""label"": ""capabilities"" + }, { ""kind"": ""csharp"", ""resource"": ""file:///Z:/TestProject.csproj"", - ""id"": 1, + ""id"": 2, ""type"": ""vertex"", ""label"": ""project"" }, { ""kind"": ""begin"", ""scope"": ""project"", - ""data"": 1, - ""id"": 2, + ""data"": 2, + ""id"": 3, ""type"": ""vertex"", ""label"": ""$event"" }, { ""uri"": ""file:///Z:/A.cs"", ""languageId"": ""csharp"", - ""id"": 3, + ""id"": 4, ""type"": ""vertex"", ""label"": ""document"" }, { ""kind"": ""begin"", ""scope"": ""document"", - ""data"": 3, - ""id"": 4, + ""data"": 4, + ""id"": 5, ""type"": ""vertex"", ""label"": ""$event"" }, { - ""outV"": 3, + ""outV"": 4, ""inVs"": [], - ""id"": 5, + ""id"": 6, ""type"": ""edge"", ""label"": ""contains"" }, { ""result"": [], - ""id"": 6, + ""id"": 7, ""type"": ""vertex"", ""label"": ""foldingRangeResult"" }, { - ""outV"": 3, + ""outV"": 4, ""inVs"": [ - 6 + 7 ], - ""id"": 7, + ""id"": 8, ""type"": ""edge"", ""label"": ""textDocument/foldingRange"" }, { ""kind"": ""end"", ""scope"": ""document"", - ""data"": 3, - ""id"": 8, + ""data"": 4, + ""id"": 9, ""type"": ""vertex"", ""label"": ""$event"" }, { - ""outV"": 1, + ""outV"": 2, ""inVs"": [ - 3 + 4 ], - ""id"": 9, + ""id"": 10, ""type"": ""edge"", ""label"": ""contains"" }, { ""kind"": ""end"", ""scope"": ""project"", - ""data"": 1, - ""id"": 10, + ""data"": 2, + ""id"": 11, ""type"": ""vertex"", ""label"": ""$event"" } diff --git a/src/Features/Lsif/GeneratorTest/Utilities/TestLsifOutput.vb b/src/Features/Lsif/GeneratorTest/Utilities/TestLsifOutput.vb index 3e8f98eab3b61..1c3fe9031bc43 100644 --- a/src/Features/Lsif/GeneratorTest/Utilities/TestLsifOutput.vb +++ b/src/Features/Lsif/GeneratorTest/Utilities/TestLsifOutput.vb @@ -27,7 +27,7 @@ Namespace Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.UnitTests.U End Function Public Shared Async Function GenerateForWorkspaceAsync(workspace As TestWorkspace, jsonWriter As ILsifJsonWriter) As Task - Dim generator = New Generator(jsonWriter) + Dim lsifGenerator = Generator.CreateAndWriteCapabilitiesVertex(jsonWriter) For Each project In workspace.CurrentSolution.Projects Dim compilation = Await project.GetCompilationAsync() @@ -35,7 +35,7 @@ Namespace Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.UnitTests.U ' Assert we don't have any errors to prevent any typos in the tests Assert.Empty(compilation.GetDiagnostics().Where(Function(d) d.Severity = DiagnosticSeverity.Error)) - generator.GenerateForCompilation(compilation, project.FilePath, project.LanguageServices, project.Solution.Options) + lsifGenerator.GenerateForCompilation(compilation, project.FilePath, project.LanguageServices, project.Solution.Options) Next End Function