diff --git a/.build/.build.csproj b/.build/.build.csproj
index 509faac59..b158ccf34 100644
--- a/.build/.build.csproj
+++ b/.build/.build.csproj
@@ -11,7 +11,6 @@
-
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 9c9be2115..ec11fff2b 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -79,7 +79,7 @@ jobs:
runs-on: ${{ matrix.os }}
steps:
- name: Checkout
- uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4.0.0
+ uses: actions/checkout@v4.0.0
with:
clean: 'false'
fetch-depth: '0'
@@ -117,7 +117,7 @@ jobs:
run: |
dotnet nuke Pack --skip
- name: 🐿 Publish Coverage
- uses: codecov/codecov-action@v4
+ uses: codecov/codecov-action@v4.0.0-beta.2
with:
name: 'actions-${{ matrix.os }}'
- name: 🏺 Publish logs
diff --git a/.github/workflows/close-milestone.yml b/.github/workflows/close-milestone.yml
index 48c4ed612..5bdb84908 100644
--- a/.github/workflows/close-milestone.yml
+++ b/.github/workflows/close-milestone.yml
@@ -10,7 +10,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
- uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4.0.0
+ uses: actions/checkout@v4.0.0
with:
fetch-depth: 0
diff --git a/.github/workflows/draft-release.yml b/.github/workflows/draft-release.yml
index da4198773..279a744f2 100644
--- a/.github/workflows/draft-release.yml
+++ b/.github/workflows/draft-release.yml
@@ -14,7 +14,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
- uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4.0.0
+ uses: actions/checkout@v4.0.0
with:
fetch-depth: 0
diff --git a/.github/workflows/sync-labels.yml b/.github/workflows/sync-labels.yml
index dd03f5704..6b8e1de71 100644
--- a/.github/workflows/sync-labels.yml
+++ b/.github/workflows/sync-labels.yml
@@ -16,7 +16,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
- uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4.0.0
+ uses: actions/checkout@v4.0.0
- name: Run Labeler
if: success()
diff --git a/.github/workflows/update-milestone.yml b/.github/workflows/update-milestone.yml
index ebdb54332..f881a2ada 100644
--- a/.github/workflows/update-milestone.yml
+++ b/.github/workflows/update-milestone.yml
@@ -13,7 +13,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
- uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4.0.0
+ uses: actions/checkout@v4.0.0
with:
ref: ${{ github.sha }}
fetch-depth: 0
diff --git a/.gitignore b/.gitignore
index f2f6f24b6..99a0f4a92 100644
--- a/.gitignore
+++ b/.gitignore
@@ -46,3 +46,4 @@ coverage.info
/codealike.json
.tmp/
.nuke/temp/
+**/*.received.cs
diff --git a/.nuke/build.schema.json b/.nuke/build.schema.json
index f99d257e6..470cfeef1 100644
--- a/.nuke/build.schema.json
+++ b/.nuke/build.schema.json
@@ -37,6 +37,7 @@
"AppVeyor",
"AzurePipelines",
"Bamboo",
+ "Bitbucket",
"Bitrise",
"GitHubActions",
"GitLab",
diff --git a/Directory.Packages.props b/Directory.Packages.props
index d3ac5d926..201d01aac 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -35,11 +35,13 @@
-
+
+
+
diff --git a/LSP.sln b/LSP.sln
index 68d6c34bf..82baf3397 100644
--- a/LSP.sln
+++ b/LSP.sln
@@ -6,6 +6,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{D764E024-3D3
ProjectSection(SolutionItems) = preProject
src\Directory.Build.props = src\Directory.Build.props
src\Directory.Build.targets = src\Directory.Build.targets
+ src\.editorconfig = src\.editorconfig
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{2F323ED5-EBF8-45E1-B9D3-C014561B3DDA}"
@@ -38,6 +39,8 @@ EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SampleServer", "sample\SampleServer\SampleServer.csproj", "{F2067F5F-FA4E-4990-B301-E7898FC4C45F}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "sample", "sample", "{A316FCEC-81AD-45FB-93EE-C62CA09300DC}"
+ ProjectSection(SolutionItems) = preProject
+ EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Client", "src\Client\Client.csproj", "{417E95B2-5AB9-49D5-B7CD-12255472E2E7}"
EndProject
@@ -53,8 +56,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dap.Server", "src\Dap.Serve
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = ".build", ".build\.build.csproj", "{28B13787-A442-4D28-BF9A-3D65BF13AAEC}"
EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".build", ".build", "{26522B49-0743-4CBE-BA67-6D17FF65CAB9}"
-EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Shared", "src\Shared\Shared.csproj", "{18FB2302-023B-4F6F-9F6D-099B47B69D9F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dap.Tests", "test\Dap.Tests\Dap.Tests.csproj", "{6D9E5BF4-4666-476B-AC88-D108A80567F6}"
@@ -81,6 +82,67 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Protocol.Proposals", "src\P
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Lsp.Integration.Tests", "test\Lsp.Integration.Tests\Lsp.Integration.Tests.csproj", "{72A74595-A278-46F0-9C8B-3151C9681B91}"
EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "config", "config", "{93A0F406-2CEB-491E-9F40-6DA1BA67DD7C}"
+ ProjectSection(SolutionItems) = preProject
+ .config\dotnet-tools.json = .config\dotnet-tools.json
+ Directory.Build.props = Directory.Build.props
+ Directory.Packages.props = Directory.Packages.props
+ Directory.Packages.supports.props = Directory.Packages.supports.props
+ Directory.Build.targets = Directory.Build.targets
+ .editorconfig = .editorconfig
+ build.cmd = build.cmd
+ build.sh = build.sh
+ build.ps1 = build.ps1
+ GitReleaseManager.yaml = GitReleaseManager.yaml
+ .codecov.yml = .codecov.yml
+ .azure-pipelines.yml = .azure-pipelines.yml
+ .appveyor.yml = .appveyor.yml
+ azure-pipelines.nuke.yml = azure-pipelines.nuke.yml
+ GitVersion.yml = GitVersion.yml
+ .travis.yml = .travis.yml
+ LICENSE = LICENSE
+ README.md = README.md
+ .gitignore = .gitignore
+ .gitattributes = .gitattributes
+ .prettierignore = .prettierignore
+ .prettierrc = .prettierrc
+ .lintstagedrc.js = .lintstagedrc.js
+ NuGet.config = NuGet.config
+ package.json = package.json
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".github", ".github", "{19909559-F753-4337-952B-A8B5B5889959}"
+ ProjectSection(SolutionItems) = preProject
+ .github\labels.yml = .github\labels.yml
+ .github\renovate.json = .github\renovate.json
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{97924298-E17E-46E6-83CC-D9CD3B9F5E6F}"
+ ProjectSection(SolutionItems) = preProject
+ .github\workflows\ci-ignore.yml = .github\workflows\ci-ignore.yml
+ .github\workflows\draft-release.yml = .github\workflows\draft-release.yml
+ .github\workflows\publish-nuget.yml = .github\workflows\publish-nuget.yml
+ .github\workflows\dependabot-merge.yml = .github\workflows\dependabot-merge.yml
+ .github\workflows\sync-labels.yml = .github\workflows\sync-labels.yml
+ .github\workflows\close-milestone.yml = .github\workflows\close-milestone.yml
+ .github\workflows\update-milestone.yml = .github\workflows\update-milestone.yml
+ .github\workflows\ci.yml = .github\workflows\ci.yml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".husky", ".husky", "{BED6765C-97D8-406D-B782-3307132D16F0}"
+ ProjectSection(SolutionItems) = preProject
+ .husky\pre-commit = .husky\pre-commit
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".vscode", ".vscode", "{09BE8ED9-1986-40F3-A9A6-D826A7413581}"
+ ProjectSection(SolutionItems) = preProject
+ .vscode\settings.json = .vscode\settings.json
+ .vscode\csharp.code-snippets = .vscode\csharp.code-snippets
+ .vscode\launch.json = .vscode\launch.json
+ .vscode\tasks.json.old = .vscode\tasks.json.old
+ .vscode\tasks.json = .vscode\tasks.json
+ EndProjectSection
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -388,7 +450,7 @@ Global
{E540868F-438E-4F7F-BBB7-010D6CB18A57} = {D764E024-3D3F-4112-B932-2DB722A1BACC}
{F2C9D555-118E-442B-A953-9A7B58A53F33} = {D764E024-3D3F-4112-B932-2DB722A1BACC}
{E1A9123B-A236-4240-8C82-A61BD85C3BF4} = {D764E024-3D3F-4112-B932-2DB722A1BACC}
- {28B13787-A442-4D28-BF9A-3D65BF13AAEC} = {26522B49-0743-4CBE-BA67-6D17FF65CAB9}
+ {28B13787-A442-4D28-BF9A-3D65BF13AAEC} = {93A0F406-2CEB-491E-9F40-6DA1BA67DD7C}
{18FB2302-023B-4F6F-9F6D-099B47B69D9F} = {D764E024-3D3F-4112-B932-2DB722A1BACC}
{6D9E5BF4-4666-476B-AC88-D108A80567F6} = {2F323ED5-EBF8-45E1-B9D3-C014561B3DDA}
{678A4DD2-A656-4DCC-AE78-F9940C82A6E6} = {D764E024-3D3F-4112-B932-2DB722A1BACC}
@@ -402,6 +464,10 @@ Global
{D43637CC-94E6-4ED4-BAA3-E5D1AD3285F5} = {D764E024-3D3F-4112-B932-2DB722A1BACC}
{201B1CA7-AB12-41AD-9246-BC30F2EBE2DF} = {D764E024-3D3F-4112-B932-2DB722A1BACC}
{72A74595-A278-46F0-9C8B-3151C9681B91} = {2F323ED5-EBF8-45E1-B9D3-C014561B3DDA}
+ {19909559-F753-4337-952B-A8B5B5889959} = {93A0F406-2CEB-491E-9F40-6DA1BA67DD7C}
+ {97924298-E17E-46E6-83CC-D9CD3B9F5E6F} = {19909559-F753-4337-952B-A8B5B5889959}
+ {BED6765C-97D8-406D-B782-3307132D16F0} = {93A0F406-2CEB-491E-9F40-6DA1BA67DD7C}
+ {09BE8ED9-1986-40F3-A9A6-D826A7413581} = {93A0F406-2CEB-491E-9F40-6DA1BA67DD7C}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {D38DD0EC-D095-4BCD-B8AF-2D788AF3B9AE}
diff --git a/global.json b/global.json
index 8c21be6de..e46b1d265 100644
--- a/global.json
+++ b/global.json
@@ -3,4 +3,4 @@
"version": "6.0.414",
"rollForward": "latestMinor"
}
-}
+}
\ No newline at end of file
diff --git a/language-server-protocol.sha.txt b/language-server-protocol.sha.txt
index 98fc9b305..f1d289146 100644
--- a/language-server-protocol.sha.txt
+++ b/language-server-protocol.sha.txt
@@ -1,4 +1,5 @@
-- This is the last commit we caught up with https://github.com/Microsoft/language-server-protocol/commits/gh-pages
-lastSha: bdcc0f2
+lastSha: 5fc92456c046ed980646bb95c1d2e390d5b3ef9d
+
+https://github.com/Microsoft/language-server-protocol/compare/5fc92456c046ed980646bb95c1d2e390d5b3ef9d..gh-pages
-https://github.com/Microsoft/language-server-protocol/compare/bdcc0f2..gh-pages
diff --git a/sample/SampleServer/FoldingRangeHandler.cs b/sample/SampleServer/FoldingRangeHandler.cs
index f885fe33f..54214784d 100644
--- a/sample/SampleServer/FoldingRangeHandler.cs
+++ b/sample/SampleServer/FoldingRangeHandler.cs
@@ -10,7 +10,7 @@ internal class FoldingRangeHandler : IFoldingRangeHandler
{
public FoldingRangeRegistrationOptions GetRegistrationOptions() =>
new FoldingRangeRegistrationOptions {
- DocumentSelector = DocumentSelector.ForLanguage("csharp")
+ DocumentSelector = TextDocumentSelector.ForLanguage("csharp")
};
public Task?> Handle(
@@ -30,7 +30,7 @@ CancellationToken cancellationToken
);
public FoldingRangeRegistrationOptions GetRegistrationOptions(FoldingRangeCapability capability, ClientCapabilities clientCapabilities) => new FoldingRangeRegistrationOptions {
- DocumentSelector = DocumentSelector.ForLanguage("csharp")
+ DocumentSelector = TextDocumentSelector.ForLanguage("csharp")
};
}
}
diff --git a/sample/SampleServer/SampleServer.csproj b/sample/SampleServer/SampleServer.csproj
index c7a131ab7..0300dcca5 100644
--- a/sample/SampleServer/SampleServer.csproj
+++ b/sample/SampleServer/SampleServer.csproj
@@ -10,16 +10,10 @@
-
-
-
-
-
-
-
-
-
-
+
+
+
+
diff --git a/sample/SampleServer/SemanticTokensHandler.cs b/sample/SampleServer/SemanticTokensHandler.cs
index a95635c3d..0f8c3d517 100644
--- a/sample/SampleServer/SemanticTokensHandler.cs
+++ b/sample/SampleServer/SemanticTokensHandler.cs
@@ -95,7 +95,7 @@ protected override SemanticTokensRegistrationOptions CreateRegistrationOptions(
{
return new SemanticTokensRegistrationOptions
{
- DocumentSelector = DocumentSelector.ForLanguage("csharp"),
+ DocumentSelector = TextDocumentSelector.ForLanguage("csharp"),
Legend = new SemanticTokensLegend
{
TokenModifiers = capability.TokenModifiers,
diff --git a/sample/SampleServer/TextDocumentHandler.cs b/sample/SampleServer/TextDocumentHandler.cs
index f3b6f9c2f..e9a06b74a 100644
--- a/sample/SampleServer/TextDocumentHandler.cs
+++ b/sample/SampleServer/TextDocumentHandler.cs
@@ -25,8 +25,8 @@ internal class TextDocumentHandler : TextDocumentSyncHandlerBase
private readonly ILogger _logger;
private readonly ILanguageServerConfiguration _configuration;
- private readonly DocumentSelector _documentSelector = new DocumentSelector(
- new DocumentFilter {
+ private readonly TextDocumentSelector _textDocumentSelector = new TextDocumentSelector(
+ new TextDocumentFilter {
Pattern = "**/*.cs"
}
);
@@ -69,8 +69,8 @@ public override Task Handle(DidCloseTextDocumentParams notification, Cance
public override Task Handle(DidSaveTextDocumentParams notification, CancellationToken token) => Unit.Task;
- protected override TextDocumentSyncRegistrationOptions CreateRegistrationOptions(SynchronizationCapability capability, ClientCapabilities clientCapabilities) => new TextDocumentSyncRegistrationOptions() {
- DocumentSelector = _documentSelector,
+ protected override TextDocumentSyncRegistrationOptions CreateRegistrationOptions(TextSynchronizationCapability capability, ClientCapabilities clientCapabilities) => new TextDocumentSyncRegistrationOptions() {
+ DocumentSelector = _textDocumentSelector,
Change = Change,
Save = new SaveOptions() { IncludeText = true }
};
@@ -129,7 +129,7 @@ CancellationToken cancellationToken
}
public DocumentSymbolRegistrationOptions GetRegistrationOptions(DocumentSymbolCapability capability, ClientCapabilities clientCapabilities) => new DocumentSymbolRegistrationOptions {
- DocumentSelector = DocumentSelector.ForLanguage("csharp")
+ DocumentSelector = TextDocumentSelector.ForLanguage("csharp")
};
}
@@ -146,7 +146,7 @@ public MyWorkspaceSymbolsHandler(IServerWorkDoneManager serverWorkDoneManager, I
_logger = logger;
}
- public async Task> Handle(
+ public async Task> Handle(
WorkspaceSymbolParams request,
CancellationToken cancellationToken
)
@@ -190,9 +190,8 @@ CancellationToken cancellationToken
partialResults.OnNext(
new[] {
- new SymbolInformation {
+ new WorkspaceSymbol {
ContainerName = "Partial Container",
- Deprecated = true,
Kind = SymbolKind.Constant,
Location = new Location {
Range = new Range(
@@ -221,15 +220,14 @@ CancellationToken cancellationToken
);
partialResults.OnCompleted();
- return new SymbolInformation[] { };
+ return new WorkspaceSymbol[] { };
}
try
{
return new[] {
- new SymbolInformation {
+ new WorkspaceSymbol {
ContainerName = "Container",
- Deprecated = true,
Kind = SymbolKind.Constant,
Location = new Location {
Range = new Range(
diff --git a/src/Client/DefaultLanguageClientFacade.cs b/src/Client/DefaultLanguageClientFacade.cs
index d5ae45489..cab0129d2 100644
--- a/src/Client/DefaultLanguageClientFacade.cs
+++ b/src/Client/DefaultLanguageClientFacade.cs
@@ -13,6 +13,7 @@ namespace OmniSharp.Extensions.LanguageServer.Client
internal class DefaultLanguageClientFacade : LanguageProtocolProxy, ILanguageClientFacade, IOnLanguageClientStarted
{
private readonly Lazy _textDocument;
+ private readonly Lazy _notebookDocument;
private readonly Lazy _client;
private readonly Lazy _general;
private readonly Lazy _window;
@@ -28,6 +29,7 @@ public DefaultLanguageClientFacade(
IProgressManager progressManager,
ILanguageProtocolSettings languageProtocolSettings,
Lazy textDocument,
+ Lazy notebookDocument,
Lazy client,
Lazy general,
Lazy window,
@@ -38,6 +40,7 @@ IInsanceHasStarted instanceHasStarted
) : base(requestRouter, resolverContext, progressManager, languageProtocolSettings)
{
_textDocument = textDocument;
+ _notebookDocument = notebookDocument;
_client = client;
_general = general;
_window = window;
@@ -48,6 +51,7 @@ IInsanceHasStarted instanceHasStarted
}
public ITextDocumentLanguageClient TextDocument => _textDocument.Value;
+ public INotebookDocumentLanguageClient NotebookDocument => _notebookDocument.Value;
public IClientLanguageClient Client => _client.Value;
public IGeneralLanguageClient General => _general.Value;
public IWindowLanguageClient Window => _window.Value;
diff --git a/src/Client/LanguageClient.cs b/src/Client/LanguageClient.cs
index 633634784..22c7004df 100644
--- a/src/Client/LanguageClient.cs
+++ b/src/Client/LanguageClient.cs
@@ -177,6 +177,7 @@ internal LanguageClient(
IEnumerable startedDelegates,
IEnumerable startedHandlers,
ITextDocumentLanguageClient textDocumentLanguageClient,
+ INotebookDocumentLanguageClient notebookDocumentLanguageClient,
IClientLanguageClient clientLanguageClient,
IGeneralLanguageClient generalLanguageClient,
IWindowLanguageClient windowLanguageClient,
@@ -228,6 +229,7 @@ IScheduler scheduler
// We need to at least create Window here in case any handler does loggin in their constructor
TextDocument = textDocumentLanguageClient;
+ NotebookDocument = notebookDocumentLanguageClient;
Client = clientLanguageClient;
General = generalLanguageClient;
Window = windowLanguageClient;
@@ -235,6 +237,7 @@ IScheduler scheduler
}
public ITextDocumentLanguageClient TextDocument { get; }
+ public INotebookDocumentLanguageClient NotebookDocument { get; }
public IClientLanguageClient Client { get; }
public IGeneralLanguageClient General { get; }
public IWindowLanguageClient Window { get; }
diff --git a/src/Client/LanguageClientRegistrationManager.cs b/src/Client/LanguageClientRegistrationManager.cs
index b6703e4c3..19bcfc48e 100644
--- a/src/Client/LanguageClientRegistrationManager.cs
+++ b/src/Client/LanguageClientRegistrationManager.cs
@@ -180,14 +180,14 @@ public IObservable> Registrations
public IEnumerable GetRegistrationsForMethod(string method) => _registrations.Select(z => z.Value).Where(x => x.Method == method);
- public IEnumerable GetRegistrationsMatchingSelector(DocumentSelector documentSelector) =>
+ public IEnumerable GetRegistrationsMatchingSelector(TextDocumentSelector textDocumentSelector) =>
_registrations
.Select(z => z.Value)
.Where(
x => x.RegisterOptions is ITextDocumentRegistrationOptions { DocumentSelector: { } } ro &&
ro.DocumentSelector
.Join(
- documentSelector,
+ textDocumentSelector,
z => z.HasLanguage ? z.Language :
z.HasScheme ? z.Scheme :
z.HasPattern ? z.Pattern : string.Empty,
diff --git a/src/Client/LanguageClientServiceCollectionExtensions.cs b/src/Client/LanguageClientServiceCollectionExtensions.cs
index a0e3c8b3c..cb0433cbf 100644
--- a/src/Client/LanguageClientServiceCollectionExtensions.cs
+++ b/src/Client/LanguageClientServiceCollectionExtensions.cs
@@ -44,6 +44,9 @@ internal static IContainer AddLanguageClientInternals(this IContainer container,
container.RegisterMany(
serviceTypeCondition: type => type.Name.Contains(nameof(TextDocumentLanguageClient)), reuse: Reuse.Singleton
);
+ container.RegisterMany(
+ serviceTypeCondition: type => type.Name.Contains(nameof(NotebookDocumentLanguageClient)), reuse: Reuse.Singleton
+ );
container.RegisterMany(
serviceTypeCondition: type => type.Name.Contains(nameof(ClientLanguageClient)), reuse: Reuse.Singleton
);
diff --git a/src/Dap.Protocol/Dap.Protocol.csproj b/src/Dap.Protocol/Dap.Protocol.csproj
index 4622960c4..52c4b5467 100644
--- a/src/Dap.Protocol/Dap.Protocol.csproj
+++ b/src/Dap.Protocol/Dap.Protocol.csproj
@@ -14,35 +14,24 @@
-
+
- <_Parameter1
- >OmniSharp.Extensions.DebugAdapter.Testing, PublicKey=0024000004800000940000000602000000240000525341310004000001000100391db875e68eb4bfef49ce14313b9e13f2cd3cc89eb273bbe6c11a55044c7d4f566cf092e1c77ef9e7c75b1496ae7f95d925938f5a01793dd8d9f99ae0a7595779b71b971287d7d7b5960d052078d14f5ce1a85ea5c9fb2f59ac735ff7bc215cab469b7c3486006860bad6f4c3b5204ea2f28dd4e1d05e2cca462cfd593b9f9f
+ <_Parameter1>OmniSharp.Extensions.DebugAdapter.Testing, PublicKey=0024000004800000940000000602000000240000525341310004000001000100391db875e68eb4bfef49ce14313b9e13f2cd3cc89eb273bbe6c11a55044c7d4f566cf092e1c77ef9e7c75b1496ae7f95d925938f5a01793dd8d9f99ae0a7595779b71b971287d7d7b5960d052078d14f5ce1a85ea5c9fb2f59ac735ff7bc215cab469b7c3486006860bad6f4c3b5204ea2f28dd4e1d05e2cca462cfd593b9f9f
- <_Parameter1
- >OmniSharp.Extensions.DebugAdapter.Server, PublicKey=0024000004800000940000000602000000240000525341310004000001000100391db875e68eb4bfef49ce14313b9e13f2cd3cc89eb273bbe6c11a55044c7d4f566cf092e1c77ef9e7c75b1496ae7f95d925938f5a01793dd8d9f99ae0a7595779b71b971287d7d7b5960d052078d14f5ce1a85ea5c9fb2f59ac735ff7bc215cab469b7c3486006860bad6f4c3b5204ea2f28dd4e1d05e2cca462cfd593b9f9f
+ <_Parameter1>OmniSharp.Extensions.DebugAdapter.Server, PublicKey=0024000004800000940000000602000000240000525341310004000001000100391db875e68eb4bfef49ce14313b9e13f2cd3cc89eb273bbe6c11a55044c7d4f566cf092e1c77ef9e7c75b1496ae7f95d925938f5a01793dd8d9f99ae0a7595779b71b971287d7d7b5960d052078d14f5ce1a85ea5c9fb2f59ac735ff7bc215cab469b7c3486006860bad6f4c3b5204ea2f28dd4e1d05e2cca462cfd593b9f9f
- <_Parameter1
- >OmniSharp.Extensions.DebugAdapter.Client, PublicKey=0024000004800000940000000602000000240000525341310004000001000100391db875e68eb4bfef49ce14313b9e13f2cd3cc89eb273bbe6c11a55044c7d4f566cf092e1c77ef9e7c75b1496ae7f95d925938f5a01793dd8d9f99ae0a7595779b71b971287d7d7b5960d052078d14f5ce1a85ea5c9fb2f59ac735ff7bc215cab469b7c3486006860bad6f4c3b5204ea2f28dd4e1d05e2cca462cfd593b9f9f
+ <_Parameter1>OmniSharp.Extensions.DebugAdapter.Client, PublicKey=0024000004800000940000000602000000240000525341310004000001000100391db875e68eb4bfef49ce14313b9e13f2cd3cc89eb273bbe6c11a55044c7d4f566cf092e1c77ef9e7c75b1496ae7f95d925938f5a01793dd8d9f99ae0a7595779b71b971287d7d7b5960d052078d14f5ce1a85ea5c9fb2f59ac735ff7bc215cab469b7c3486006860bad6f4c3b5204ea2f28dd4e1d05e2cca462cfd593b9f9f
- <_Parameter1
- >OmniSharp.Extensions.DebugAdapter.Shared, PublicKey=0024000004800000940000000602000000240000525341310004000001000100391db875e68eb4bfef49ce14313b9e13f2cd3cc89eb273bbe6c11a55044c7d4f566cf092e1c77ef9e7c75b1496ae7f95d925938f5a01793dd8d9f99ae0a7595779b71b971287d7d7b5960d052078d14f5ce1a85ea5c9fb2f59ac735ff7bc215cab469b7c3486006860bad6f4c3b5204ea2f28dd4e1d05e2cca462cfd593b9f9f
+ <_Parameter1>OmniSharp.Extensions.DebugAdapter.Shared, PublicKey=0024000004800000940000000602000000240000525341310004000001000100391db875e68eb4bfef49ce14313b9e13f2cd3cc89eb273bbe6c11a55044c7d4f566cf092e1c77ef9e7c75b1496ae7f95d925938f5a01793dd8d9f99ae0a7595779b71b971287d7d7b5960d052078d14f5ce1a85ea5c9fb2f59ac735ff7bc215cab469b7c3486006860bad6f4c3b5204ea2f28dd4e1d05e2cca462cfd593b9f9f
- <_Parameter1
- >OmniSharp.Extensions.DebugAdapter.Proposals, PublicKey=0024000004800000940000000602000000240000525341310004000001000100391db875e68eb4bfef49ce14313b9e13f2cd3cc89eb273bbe6c11a55044c7d4f566cf092e1c77ef9e7c75b1496ae7f95d925938f5a01793dd8d9f99ae0a7595779b71b971287d7d7b5960d052078d14f5ce1a85ea5c9fb2f59ac735ff7bc215cab469b7c3486006860bad6f4c3b5204ea2f28dd4e1d05e2cca462cfd593b9f9f
+ <_Parameter1>OmniSharp.Extensions.DebugAdapter.Proposals, PublicKey=0024000004800000940000000602000000240000525341310004000001000100391db875e68eb4bfef49ce14313b9e13f2cd3cc89eb273bbe6c11a55044c7d4f566cf092e1c77ef9e7c75b1496ae7f95d925938f5a01793dd8d9f99ae0a7595779b71b971287d7d7b5960d052078d14f5ce1a85ea5c9fb2f59ac735ff7bc215cab469b7c3486006860bad6f4c3b5204ea2f28dd4e1d05e2cca462cfd593b9f9f
diff --git a/src/JsonRpc.Generators/ActionContextExtensions.cs b/src/JsonRpc.Generators/ActionContextExtensions.cs
index f555d9dc4..1c6df349f 100644
--- a/src/JsonRpc.Generators/ActionContextExtensions.cs
+++ b/src/JsonRpc.Generators/ActionContextExtensions.cs
@@ -1,6 +1,7 @@
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using OmniSharp.Extensions.JsonRpc.Generators.Contexts;
+using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
namespace OmniSharp.Extensions.JsonRpc.Generators
{
@@ -8,12 +9,12 @@ static class ActionContextExtensions
{
public static ParameterListSyntax GetRegistryParameterList(this ExtensionMethodContext extensionMethodContext)
{
- return SyntaxFactory.ParameterList(
- SyntaxFactory.SeparatedList(
+ return ParameterList(
+ SeparatedList(
new[] {
- SyntaxFactory.Parameter(SyntaxFactory.Identifier("registry"))
+ Parameter(Identifier("registry"))
.WithType(extensionMethodContext.Item)
- .WithModifiers(SyntaxFactory.TokenList(SyntaxFactory.Token(SyntaxKind.ThisKeyword)))
+ .WithModifiers(TokenList(Token(SyntaxKind.ThisKeyword)))
}
)
);
diff --git a/src/JsonRpc.Generators/AutoImplementParamsGenerator.cs b/src/JsonRpc.Generators/AutoImplementParamsGenerator.cs
index c9eac05da..45b3f9f94 100644
--- a/src/JsonRpc.Generators/AutoImplementParamsGenerator.cs
+++ b/src/JsonRpc.Generators/AutoImplementParamsGenerator.cs
@@ -16,7 +16,7 @@ public class AutoImplementParamsGenerator : IIncrementalGenerator
public void Initialize(IncrementalGeneratorInitializationContext context)
{
var _attributes = "Method,RegistrationOptions";
- var _interfaces = "IPartialItemsRequest,IPartialItemRequest,IWorkDoneProgressParams,IHandlerIdentity";
+ var _interfaces = "IPartialItemsRequest,IPartialItemsWithInitialValueRequest,IPartialItemRequest,IPartialItemWithInitialValueRequest,IWorkDoneProgressParams,IHandlerIdentity";
var syntaxProvider = context.SyntaxProvider.CreateSyntaxProvider(
(syntaxNode, _) =>
@@ -102,7 +102,7 @@ private static IEnumerable AutoImplementInterfaces(Base
.WithAccessorList(GetInitAccessor);
}
- if (syntax.BaseList?.Types.Any(z => z.Type.GetSyntaxName() is "IPartialItemsRequest" or "IPartialItemRequest") == true
+ if (syntax.BaseList?.Types.Any(z => z.Type.GetSyntaxName() is "IPartialItemsRequest" or "IPartialItemRequest" or "IPartialItemsWithInitialValueRequest" or "IPartialItemWithInitialValueRequest") == true
&& symbol.GetMembers("PartialResultToken").IsEmpty)
{
yield return PropertyDeclaration(NullableType(IdentifierName("ProgressToken")), Identifier("PartialResultToken"))
diff --git a/src/JsonRpc.Generators/Contexts/GeneratorData.cs b/src/JsonRpc.Generators/Contexts/GeneratorData.cs
index 33cffce86..f83292bda 100644
--- a/src/JsonRpc.Generators/Contexts/GeneratorData.cs
+++ b/src/JsonRpc.Generators/Contexts/GeneratorData.cs
@@ -43,6 +43,7 @@ HashSet additionalUsings
if (IsRequest(candidateClass))
{
var responseType = GetResponseType(candidateClass, symbol);
+ var (partialItem, inheritsFromSelf) = GetPartialItem(candidateClass, symbol, requestType, compilation);
return new RequestItem(
candidateClass,
symbol,
@@ -54,8 +55,10 @@ HashSet additionalUsings
responseType.Syntax.GetSyntaxName() == "Unit",
GetCapability(candidateClass, symbol, lspAttributes),
GetRegistrationOptions(candidateClass, symbol, lspAttributes),
- GetPartialItem(candidateClass, symbol, requestType),
+ partialItem,
GetPartialItems(candidateClass, symbol, requestType),
+ symbol.AllInterfaces.Concat(requestType.Symbol.AllInterfaces).Any(z => z.Name.EndsWith("WithInitialValue", StringComparison.Ordinal)),
+ inheritsFromSelf,
additionalUsings,
new List(),
model, compilation
diff --git a/src/JsonRpc.Generators/Contexts/RegistrationOptionAttributes.cs b/src/JsonRpc.Generators/Contexts/RegistrationOptionAttributes.cs
index 28b59670c..226500e35 100644
--- a/src/JsonRpc.Generators/Contexts/RegistrationOptionAttributes.cs
+++ b/src/JsonRpc.Generators/Contexts/RegistrationOptionAttributes.cs
@@ -11,11 +11,13 @@ internal record RegistrationOptionAttributes(
string? Key,
ExpressionSyntax[]? KeyExpression,
bool SupportsWorkDoneProgress,
- bool SupportsDocumentSelector,
+ bool SupportsTextDocumentSelector,
+ bool SupportsNotebookDocumentSelector,
bool SupportsStaticRegistrationOptions,
SyntaxSymbol? RegistrationOptionsConverter,
bool ImplementsWorkDoneProgress,
- bool ImplementsDocumentSelector,
+ bool ImplementsTextDocumentSelector,
+ bool ImplementsNotebookDocumentSelector,
bool ImplementsStaticRegistrationOptions
)
{
@@ -28,24 +30,33 @@ bool ImplementsStaticRegistrationOptions
// var registrationOptionsInterfaceSymbol = compilation.GetTypeByMetadataName("OmniSharp.Extensions.LanguageServer.Protocol.IRegistrationOptions");
var textDocumentRegistrationOptionsInterfaceSymbol =
compilation.GetTypeByMetadataName("OmniSharp.Extensions.LanguageServer.Protocol.Models.ITextDocumentRegistrationOptions");
+ var notebookDocumentRegistrationOptionsInterfaceSymbol =
+ compilation.GetTypeByMetadataName("OmniSharp.Extensions.LanguageServer.Protocol.Models.INotebookDocumentRegistrationOptions");
var workDoneProgressOptionsInterfaceSymbol =
compilation.GetTypeByMetadataName("OmniSharp.Extensions.LanguageServer.Protocol.Models.IWorkDoneProgressOptions");
var staticRegistrationOptionsInterfaceSymbol =
compilation.GetTypeByMetadataName("OmniSharp.Extensions.LanguageServer.Protocol.Models.IStaticRegistrationOptions");
if (!( symbol.GetAttribute(registrationOptionsAttributeSymbol) is { } data )) return null;
- if (!( data.ApplicationSyntaxReference?.GetSyntax() is AttributeSyntax attributeSyntax )) return null;
+ if (data.ApplicationSyntaxReference?.GetSyntax() is not AttributeSyntax attributeSyntax) return null;
TypeSyntax? converterSyntax = null;
ITypeSymbol? converter = null;
- var supportsDocumentSelector = data.NamedArguments.Any(z => z is { Key: nameof(SupportsDocumentSelector), Value: { Value: true } })
+ var supportsTextDocumentSelector = data.NamedArguments.Any(z => z is { Key: nameof(SupportsTextDocumentSelector), Value: { Value: true } })
|| ( symbol.AllInterfaces.Length > 0 && symbol.AllInterfaces.Any(
z => SymbolEqualityComparer.Default.Equals(z, textDocumentRegistrationOptionsInterfaceSymbol)
) )
|| ( textDocumentRegistrationOptionsInterfaceSymbol is { } && syntax.BaseList?.Types.Any(
type => type.Type.GetSyntaxName()?.Contains(textDocumentRegistrationOptionsInterfaceSymbol.Name) == true
) == true );
+ var supportsNotebookDocumentSelector = data.NamedArguments.Any(z => z is { Key: nameof(SupportsNotebookDocumentSelector), Value: { Value: true } })
+ || ( symbol.AllInterfaces.Length > 0 && symbol.AllInterfaces.Any(
+ z => SymbolEqualityComparer.Default.Equals(z, notebookDocumentRegistrationOptionsInterfaceSymbol)
+ ) )
+ || ( notebookDocumentRegistrationOptionsInterfaceSymbol is { } && syntax.BaseList?.Types.Any(
+ type => type.Type.GetSyntaxName()?.Contains(notebookDocumentRegistrationOptionsInterfaceSymbol.Name) == true
+ ) == true );
var supportsWorkDoneProgress = data.NamedArguments.Any(z => z is { Key: nameof(SupportsWorkDoneProgress), Value: { Value: true } })
|| ( symbol.AllInterfaces.Length > 0 && symbol.AllInterfaces.Any(
z => SymbolEqualityComparer.Default.Equals(z, workDoneProgressOptionsInterfaceSymbol)
@@ -135,7 +146,8 @@ static IEnumerable getStringExpressionSyntaxes(AttributeArgume
value,
valueExpressionSyntaxes,
supportsWorkDoneProgress,
- supportsDocumentSelector,
+ supportsTextDocumentSelector,
+ supportsNotebookDocumentSelector,
supportsStaticRegistrationOptions,
converterSyntax is null ? null : new SyntaxSymbol(converterSyntax, (INamedTypeSymbol)converter!),
symbol
@@ -156,6 +168,15 @@ static IEnumerable getStringExpressionSyntaxes(AttributeArgume
.AsEnumerable()
.Any(x => SymbolEqualityComparer.Default.Equals(z, x)) == true
),
+ symbol
+ .GetMembers()
+ .AsEnumerable()
+ .All(
+ z => notebookDocumentRegistrationOptionsInterfaceSymbol?
+ .GetMembers()
+ .AsEnumerable()
+ .Any(x => SymbolEqualityComparer.Default.Equals(z, x)) == true
+ ),
symbol
.GetMembers()
.AsEnumerable()
diff --git a/src/JsonRpc.Generators/Contexts/RequestItem.cs b/src/JsonRpc.Generators/Contexts/RequestItem.cs
index 3b5103243..5d3af252e 100644
--- a/src/JsonRpc.Generators/Contexts/RequestItem.cs
+++ b/src/JsonRpc.Generators/Contexts/RequestItem.cs
@@ -17,6 +17,8 @@ record RequestItem(
SyntaxSymbol? RegistrationOptions,
SyntaxSymbol? PartialItem,
SyntaxSymbol? PartialItems,
+ bool PartialHasInitialValue,
+ bool PartialItemInheritsFromSelf,
HashSet AdditionalUsings,
List AssemblyJsonRpcHandlersAttributeArguments,
SemanticModel Model,
diff --git a/src/JsonRpc.Generators/DelegateHelpers.cs b/src/JsonRpc.Generators/DelegateHelpers.cs
index 677afcaab..cd82c89ff 100644
--- a/src/JsonRpc.Generators/DelegateHelpers.cs
+++ b/src/JsonRpc.Generators/DelegateHelpers.cs
@@ -29,25 +29,25 @@ public static Func MakeGenericFactory(Func<
);
}
- public static Func MakeGenericFactory(
- Func factory, TypeSyntax constraint
+ public static Func MakeGenericFactory(
+ Func factory, TypeSyntax constraint
)
{
- return (syntax, resolveSyntax) => factory(syntax, resolveSyntax)
- .WithTypeParameterList(TypeParameterList(SingletonSeparatedList(TypeParameter(Identifier("T")))))
- .WithConstraintClauses(
- SingletonList(
- TypeParameterConstraintClause(IdentifierName("T"))
- .WithConstraints(SingletonSeparatedList(TypeConstraint(constraint)))
- )
- );
+ return (syntax, resolveSyntax, initialValueHandler) => factory(syntax, resolveSyntax, initialValueHandler)
+ .WithTypeParameterList(TypeParameterList(SingletonSeparatedList(TypeParameter(Identifier("T")))))
+ .WithConstraintClauses(
+ SingletonList(
+ TypeParameterConstraintClause(IdentifierName("T"))
+ .WithConstraints(SingletonSeparatedList(TypeConstraint(constraint)))
+ )
+ );
}
- public static Func> MakeGenericFactory(
- Func> factory, TypeSyntax constraint
+ public static Func> MakeGenericFactory(
+ Func> factory, TypeSyntax constraint
)
{
- return (syntax, resolveSyntax) => factory(syntax, resolveSyntax)
+ return (syntax, resolveSyntax, initialValueHandler) => factory(syntax, resolveSyntax, initialValueHandler)
.Select(
method => method
.WithTypeParameterList(TypeParameterList(SingletonSeparatedList(TypeParameter(Identifier("T")))))
diff --git a/src/JsonRpc.Generators/GenerateHandlerMethodsGenerator.cs b/src/JsonRpc.Generators/GenerateHandlerMethodsGenerator.cs
index 51e875466..24cfc1473 100644
--- a/src/JsonRpc.Generators/GenerateHandlerMethodsGenerator.cs
+++ b/src/JsonRpc.Generators/GenerateHandlerMethodsGenerator.cs
@@ -48,12 +48,19 @@ syntaxNode is TypeDeclarationSyntax tds
actionItem = GeneratorData.Create(
compilaiton, (TypeDeclarationSyntax)syntaxContext.Node, syntaxContext.SemanticModel, additionalUsings
);
+ if (actionItem is null)
+ {
+ diagnostic = Diagnostic.Create(
+ GeneratorDiagnostics.MustBeARequestOrNotification, syntaxContext.Node.GetLocation(),
+ ( (TypeDeclarationSyntax)syntaxContext.Node ).Identifier.Text
+ );
+ }
}
catch (Exception e)
{
diagnostic = Diagnostic.Create(
GeneratorDiagnostics.Exception, syntaxContext.Node.GetLocation(), e.Message,
- e.StackTrace ?? string.Empty
+ e.StackTrace?.Replace("\n", " ") ?? string.Empty, e.ToString()
);
Debug.WriteLine(e);
Debug.WriteLine(e.StackTrace);
@@ -81,7 +88,7 @@ private void GenerateHandlerMethods(
if (actionItem is null)
{
- context.ReportDiagnostic(diagnostic!);
+ if (diagnostic is { }) context.ReportDiagnostic(diagnostic);
return;
}
@@ -99,7 +106,7 @@ private void GenerateHandlerMethods(
context.ReportDiagnostic(
Diagnostic.Create(
GeneratorDiagnostics.Exception, candidateClass.GetLocation(),
- $"Strategy {strategy.GetType().FullName} failed!" + " - " + e.Message, e.StackTrace ?? string.Empty
+ $"Strategy {strategy.GetType().FullName} failed!" + " - " + e.Message, e.StackTrace?.Replace("\n", " ") ?? string.Empty
)
);
Debug.WriteLine($"Strategy {strategy.GetType().FullName} failed!");
@@ -194,11 +201,14 @@ private static ImmutableArray GetCompilationU
new OnRequestMethodGeneratorWithoutRegistrationOptionsStrategy(false),
new OnRequestMethodGeneratorWithoutRegistrationOptionsStrategy(true),
new OnRequestTypedResolveMethodGeneratorWithoutRegistrationOptionsStrategy(),
+// new OnRequestTypedMethodGeneratorWithoutRegistrationOptionsStrategy(),
new OnRequestMethodGeneratorWithRegistrationOptionsStrategy(false),
new OnRequestMethodGeneratorWithRegistrationOptionsStrategy(true),
new OnRequestTypedResolveMethodGeneratorWithRegistrationOptionsStrategy(),
+// new OnRequestTypedMethodGeneratorWithRegistrationOptionsStrategy(),
new SendMethodNotificationStrategy(),
- new SendMethodRequestStrategy()
+ new SendMethodRequestStrategy()/*,
+ new SendMethodTypedResolveRequestStrategy()*/
);
var actionStrategies = ImmutableArray.Create(
new EnsureNamespaceStrategy(),
diff --git a/src/JsonRpc.Generators/GeneratorDiagnostics.cs b/src/JsonRpc.Generators/GeneratorDiagnostics.cs
index b93e808c5..42ae8b41a 100644
--- a/src/JsonRpc.Generators/GeneratorDiagnostics.cs
+++ b/src/JsonRpc.Generators/GeneratorDiagnostics.cs
@@ -8,7 +8,11 @@ internal static class GeneratorDiagnostics
{
public static DiagnosticDescriptor Exception { get; } = new DiagnosticDescriptor(
"JRPC0001", "Exception",
- "{0} - {1}", "JRPC", DiagnosticSeverity.Error, true
+ "{0} - {1} {2}", "JRPC", DiagnosticSeverity.Error, true
+ );
+ public static DiagnosticDescriptor ExceptionWarning { get; } = new DiagnosticDescriptor(
+ "JRPC0002", "Exception",
+ "{0} - {1} {2}", "JRPC", DiagnosticSeverity.Warning, true
);
public static DiagnosticDescriptor NoHandlerRegistryProvided { get; } = new DiagnosticDescriptor(
@@ -41,6 +45,11 @@ internal static class GeneratorDiagnostics
"Type {0} must be made readonly.", "JsonRPC", DiagnosticSeverity.Error, true
);
+ public static DiagnosticDescriptor MustBeARequestOrNotification { get; } = new DiagnosticDescriptor(
+ "JRPC1006", "Type must implement a request or notification interface",
+ "Type {0} must implement a request or notification interface.", "JsonRPC", DiagnosticSeverity.Error, true
+ );
+
public static DiagnosticDescriptor MustInheritFromCanBeResolved { get; } = new DiagnosticDescriptor(
"LSP1001", "The target class must implement ICanBeResolved",
"The target class must implement ICanBeResolved", "LSP", DiagnosticSeverity.Error, true
diff --git a/src/JsonRpc.Generators/Helpers.cs b/src/JsonRpc.Generators/Helpers.cs
index f7559140d..7ce048f46 100644
--- a/src/JsonRpc.Generators/Helpers.cs
+++ b/src/JsonRpc.Generators/Helpers.cs
@@ -30,8 +30,8 @@ public static bool IsRequest(TypeDeclarationSyntax symbol) =>
z.Type is SimpleNameSyntax and (
{ Identifier: { Text: "IJsonRpcRequestHandler" }, Arity: 1 or 2 }
or { Identifier: { Text: "ICanBeResolvedHandler" }, Arity: 1 }
- or { Identifier: { Text: "IPartialItemRequest" }, Arity: 2 }
- or { Identifier: { Text: "IPartialItemsRequest" }, Arity: 2 }
+ or { Identifier: { Text: "IPartialItemRequest" or "IPartialItemWithInitialValueRequest" }, Arity: 2 }
+ or { Identifier: { Text: "IPartialItemsRequest" or "IPartialItemsWithInitialValueRequest" }, Arity: 2 }
or { Identifier: { Text: "IRequest" }, Arity: 1 }
or { Identifier: { Text: "IJsonRpcRequest" }, Arity: 0 }
)
@@ -51,15 +51,18 @@ public static SyntaxSymbol GetResponseType(TypeDeclarationSyntax syntax, INamedT
TypeSyntax? type = null!;
foreach (var baseType in syntax.BaseList?.Types.AsEnumerable() ?? Array.Empty())
{
- type = baseType.Type switch {
- GenericNameSyntax gns => gns switch {
- { Identifier: { Text: "IJsonRpcRequestHandler" }, Arity: 1 } => ParseName("MediatR.Unit"),
- { Identifier: { Text: "IJsonRpcRequestHandler" }, Arity: 2 } => gns.TypeArgumentList.Arguments[1],
- { Identifier: { Text: "ICanBeResolvedHandler" }, Arity: 1 } => gns.TypeArgumentList.Arguments[0],
- { Identifier: { Text: "IPartialItemRequest" }, Arity: 2 } => gns.TypeArgumentList.Arguments[0],
- { Identifier: { Text: "IPartialItemsRequest" }, Arity: 2 } => gns.TypeArgumentList.Arguments[0],
- { Identifier: { Text: "IRequest" }, Arity: 1 } => gns.TypeArgumentList.Arguments[0],
- _ => null
+ type = baseType.Type switch
+ {
+ GenericNameSyntax gns => gns switch
+ {
+ { Identifier: { Text: "IJsonRpcRequestHandler" }, Arity: 1 } => ParseName("MediatR.Unit"),
+ { Identifier: { Text: "IJsonRpcRequestHandler" }, Arity: 2 } => gns.TypeArgumentList.Arguments[1],
+ { Identifier: { Text: "ICanBeResolvedHandler" }, Arity: 1 } => gns.TypeArgumentList.Arguments[0],
+ { Identifier: { Text: "IPartialItemRequest" or "IPartialItemWithInitialValueRequest" }, Arity: 2 } => gns.TypeArgumentList.Arguments[0],
+ { Identifier: { Text: "IPartialItemsRequest" or "IPartialItemsWithInitialValueRequest" }, Arity: 2 } => gns.TypeArgumentList.Arguments
+ [0],
+ { Identifier: { Text: "IRequest" }, Arity: 1 } => gns.TypeArgumentList.Arguments[0],
+ _ => null
},
SimpleNameSyntax and { Identifier: { Text: "IRequest" } } => ParseName("MediatR.Unit"),
SimpleNameSyntax and { Identifier: { Text: "IJsonRpcRequest" } } => ParseName("MediatR.Unit"),
@@ -89,7 +92,8 @@ public static SyntaxSymbol GetResponseType(TypeDeclarationSyntax syntax, INamedT
.OfType()
.FirstOrDefault()?.Type;
}
- else if (syntax.BaseList?.Types.Select(z => z.Type).OfType().Any(z => z.Identifier.Text == "IRequest" || z.Identifier.Text == "IJsonRpcRequest")
+ else if (syntax.BaseList?.Types.Select(z => z.Type).OfType()
+ .Any(z => z.Identifier.Text == "IRequest" || z.Identifier.Text == "IJsonRpcRequest")
== true)
{
type = IdentifierName(syntax.Identifier.Text);
@@ -98,17 +102,23 @@ public static SyntaxSymbol GetResponseType(TypeDeclarationSyntax syntax, INamedT
{
foreach (var baseType in syntax.BaseList?.Types.AsEnumerable() ?? Array.Empty())
{
- type = baseType.Type switch {
- GenericNameSyntax gns => gns switch {
+ type = baseType.Type switch
+ {
+ GenericNameSyntax gns => gns switch
+ {
{ Identifier: { Text: "IJsonRpcRequestHandler" } } => gns.TypeArgumentList.Arguments[0],
{ Identifier: { Text: "IJsonRpcNotificationHandler" } } => gns.TypeArgumentList.Arguments[0],
{ Identifier: { Text: "ICanBeResolvedHandler" }, Arity: 1 } => gns.TypeArgumentList.Arguments[0],
- { Identifier: { Text: "IRequest" }, Arity: 1 } => IdentifierName(syntax.Identifier.Text),
- { Identifier: { Text: "IRequest" }, Arity: 0 } => IdentifierName(syntax.Identifier.Text),
- { Identifier: { Text: "IJsonRpcRequest" } } => IdentifierName(syntax.Identifier.Text),
- { Identifier: { Text: "IPartialItemRequest" }, Arity: 2 } => IdentifierName(syntax.Identifier.Text),
- { Identifier: { Text: "IPartialItemsRequest" }, Arity: 2 } => IdentifierName(syntax.Identifier.Text),
- _ => null,
+ { Identifier: { Text: "IRequest" }, Arity: 1 } => IdentifierName(syntax.Identifier.Text),
+ { Identifier: { Text: "IRequest" }, Arity: 0 } => IdentifierName(syntax.Identifier.Text),
+ { Identifier: { Text: "IJsonRpcRequest" } } => IdentifierName(syntax.Identifier.Text),
+ { Identifier: { Text: "IPartialItemRequest" or "IPartialItemWithInitialValueRequest" }, Arity: 2 } => IdentifierName(
+ syntax.Identifier.Text
+ ),
+ { Identifier: { Text: "IPartialItemsRequest" or "IPartialItemsWithInitialValueRequest" }, Arity: 2 } => IdentifierName(
+ syntax.Identifier.Text
+ ),
+ _ => null,
},
_ => null,
};
@@ -150,8 +160,10 @@ public static SyntaxSymbol GetResponseType(TypeDeclarationSyntax syntax, INamedT
TypeSyntax? type = null!;
foreach (var baseType in syntax.BaseList?.Types.AsEnumerable() ?? Array.Empty())
{
- type = baseType.Type switch {
- GenericNameSyntax gns => gns switch {
+ type = baseType.Type switch
+ {
+ GenericNameSyntax gns => gns switch
+ {
{ Identifier: { Text: "ICapability" }, Arity: 1 } => gns.TypeArgumentList.Arguments[0],
{ Identifier: { Text: "IRegistration" }, Arity: 2 } => gns.TypeArgumentList.Arguments[1],
_ => null
@@ -190,9 +202,10 @@ public static SyntaxSymbol GetResponseType(TypeDeclarationSyntax syntax, INamedT
TypeSyntax? type = null!;
foreach (var baseType in syntax.BaseList?.Types.AsEnumerable() ?? Array.Empty())
{
- type = baseType.Type switch {
- GenericNameSyntax gns and { Identifier: { Text: "IRegistration" }, Arity: >0 } => gns.TypeArgumentList.Arguments[0],
- _ => null
+ type = baseType.Type switch
+ {
+ GenericNameSyntax gns and { Identifier: { Text: "IRegistration" }, Arity: > 0 } => gns.TypeArgumentList.Arguments[0],
+ _ => null
};
if (type != null) break;
}
@@ -222,35 +235,42 @@ public static SyntaxSymbol GetResponseType(TypeDeclarationSyntax syntax, INamedT
public static SyntaxSymbol? GetPartialItems(TypeDeclarationSyntax syntax, INamedTypeSymbol symbol, SyntaxSymbol requestType)
{
- var handlerInterface = symbol.AllInterfaces
- .FirstOrDefault(z => z.Name == "IPartialItems" && z.TypeArguments.Length == 1)
- ?? requestType.Symbol.AllInterfaces.FirstOrDefault(z => z.Name == "IPartialItems" && z.TypeArguments.Length == 1);
+ var handlerInterface = symbol.AllInterfaces.Concat(requestType.Symbol.AllInterfaces).FirstOrDefault(
+ z => z is { Name: "IPartialItems", TypeArguments.Length: 1 } or { Name: "IPartialItemsWithInitialValue", TypeArguments.Length: 2 }
+ );
var localSymbol = handlerInterface?.TypeArguments[0] as INamedTypeSymbol;
if (localSymbol == null) return null;
var type = syntax.BaseList?.Types
.Select(z => z.Type is GenericNameSyntax genericNameSyntax ? genericNameSyntax : null)
.Where(z => z != null)
- .Where(z => z!.Identifier.Text == "IPartialItemsRequest" && z.Arity == 2)
+ .Where(z => z is { Identifier.Text: "IPartialItemsRequest" or "IPartialItemsWithInitialValueRequest", Arity: 2 })
.Select(z => z!.TypeArgumentList.Arguments[1])
.FirstOrDefault();
return new SyntaxSymbol(type ?? ResolveTypeName(localSymbol), localSymbol);
}
- public static SyntaxSymbol? GetPartialItem(TypeDeclarationSyntax syntax, INamedTypeSymbol symbol, SyntaxSymbol requestType)
+ public static (SyntaxSymbol? partialItem, bool inheritsFromSelf) GetPartialItem(
+ TypeDeclarationSyntax syntax, INamedTypeSymbol symbol, SyntaxSymbol requestType, Compilation compilation
+ )
{
- var handlerInterface = symbol.AllInterfaces
- .FirstOrDefault(z => z.Name == "IPartialItem" && z.TypeArguments.Length == 1)
- ?? requestType.Symbol.AllInterfaces.FirstOrDefault(z => z.Name == "IPartialItem" && z.TypeArguments.Length == 1);
+ var handlerInterface = symbol.AllInterfaces.Concat(requestType.Symbol.AllInterfaces)
+ .FirstOrDefault(
+ z => z is { Name: "IPartialItem", TypeArguments.Length: 1 } or
+ { Name: "IPartialItemWithInitialValue", TypeArguments.Length: 2 }
+ );
var localSymbol = handlerInterface?.TypeArguments[0] as INamedTypeSymbol;
- if (localSymbol == null) return null;
+ if (localSymbol == null) return ( null, false );
var type = syntax.BaseList?.Types
.Select(z => z.Type is GenericNameSyntax genericNameSyntax ? genericNameSyntax : null)
.Where(z => z != null)
- .Where(z => z!.Identifier.Text == "IPartialItemRequest" && z.Arity == 2)
+ .Where(z => z is { Identifier.Text: "IPartialItemRequest" or "IPartialItemWithInitialValueRequest", Arity: 2 })
.Select(z => z!.TypeArgumentList.Arguments[1])
.FirstOrDefault();
- return new SyntaxSymbol(type ?? ResolveTypeName(localSymbol), localSymbol);
+ return (
+ new SyntaxSymbol(type ?? ResolveTypeName(localSymbol), localSymbol),
+ handlerInterface!.TypeArguments.Length == 2 && compilation.HasImplicitConversion(handlerInterface!.TypeArguments[1], handlerInterface.TypeArguments[0])
+ );
}
public static NameSyntax ResolveTypeName(ITypeSymbol symbol)
@@ -270,12 +290,16 @@ public static NameSyntax ResolveTypeName(ITypeSymbol symbol)
return IdentifierName(symbol.Name);
}
- public static GenericNameSyntax CreatePartialAction(TypeSyntax requestType, TypeSyntax partialType, bool withCancellationToken, params TypeSyntax[] types)
+ public static GenericNameSyntax CreatePartialAction(
+ TypeSyntax requestType, TypeSyntax partialType, bool withCancellationToken, params TypeSyntax[] types
+ )
{
- var typeArguments = new List {
+ var typeArguments = new List
+ {
requestType,
GenericName("IObserver").WithTypeArgumentList(TypeArgumentList(SeparatedList(new[] { partialType }))),
};
+
typeArguments.AddRange(types);
if (withCancellationToken)
{
@@ -286,7 +310,9 @@ public static GenericNameSyntax CreatePartialAction(TypeSyntax requestType, Type
.WithTypeArgumentList(TypeArgumentList(SeparatedList(typeArguments)));
}
- public static ExpressionStatementSyntax EnsureRegistrationOptionsIsSet(NameSyntax registrationOptionsName, TypeSyntax registrationOptionsType, bool hasCapability) =>
+ public static ExpressionStatementSyntax EnsureRegistrationOptionsIsSet(
+ NameSyntax registrationOptionsName, TypeSyntax registrationOptionsType, bool hasCapability
+ ) =>
ExpressionStatement(
AssignmentExpression(
SyntaxKind.CoalesceAssignmentExpression,
@@ -322,31 +348,39 @@ public static InvocationExpressionSyntax AddHandler(ExpressionSyntax syntax, par
private static ArgumentListSyntax GetHandlerArgumentList() =>
ArgumentList(
SeparatedList(
- new[] {
+ new[]
+ {
HandlerArgument
}
)
);
public static ArgumentListSyntax GetRegistrationHandlerArgumentList(
- TypeSyntax registrationOptionsName, TypeSyntax registrationType, ArgumentSyntax handlerArgument, TypeSyntax? capabilityType, bool includeId
+ TypeSyntax registrationOptionsName, TypeSyntax registrationType, ArgumentSyntax handlerArgument, ArgumentSyntax? initialArgument,
+ TypeSyntax? capabilityType, bool includeId
) =>
ArgumentList(
SeparatedList(
- includeId
- ? new[] {
+ ( includeId
+ ? new[]
+ {
Argument(IdentifierName("id")),
+ initialArgument!,
handlerArgument,
Argument(GetRegistrationOptionsAdapter(registrationOptionsName, registrationType, capabilityType))
}
- : new[] {
+ : new[]
+ {
+ initialArgument!,
handlerArgument,
Argument(GetRegistrationOptionsAdapter(registrationOptionsName, registrationType, capabilityType))
- }
+ } )
+ .Where(z => z is not null)
)
);
public static ArgumentSyntax HandlerArgument = Argument(IdentifierName("handler"));
+ public static ArgumentSyntax InitialHandlerArgument = Argument(IdentifierName("initialHandler"));
public static ArgumentSyntax ResolveHandlerArgument = Argument(IdentifierName("resolveHandler"));
public static ArgumentSyntax GetHandlerAdapterArgument(
@@ -393,55 +427,62 @@ public static InvocationExpressionSyntax GetRegistrationOptionsAdapter(
.WithArgumentList(ArgumentList(SingletonSeparatedList(Argument(registrationOptionsName))));
}
- private static ArgumentListSyntax GetPartialResultArgumentList(TypeSyntax responseName, ArgumentSyntax handlerArgument) =>
- ArgumentList(
- SeparatedList(
- new[] {
- handlerArgument,
- Argument(
- InvocationExpression(
- MemberAccessExpression(
- SyntaxKind.SimpleMemberAccessExpression,
- IdentifierName("_"),
- GenericName(Identifier("GetService"))
- .WithTypeArgumentList(TypeArgumentList(SingletonSeparatedList(IdentifierName("IProgressManager"))))
- )
- )
- ),
- Argument(
+ private static SeparatedSyntaxList GetPartialResultArgumentList(
+ TypeSyntax responseName, ArgumentSyntax handlerArgument, ArgumentSyntax? initialArgument
+ ) =>
+ SeparatedList(
+ new[]
+ {
+ initialArgument!,
+ handlerArgument,
+ Argument(
+ InvocationExpression(
MemberAccessExpression(
SyntaxKind.SimpleMemberAccessExpression,
- responseName.EnsureNotNullable(),
- IdentifierName("From")
+ IdentifierName("_"),
+ GenericName(Identifier("GetService"))
+ .WithTypeArgumentList(TypeArgumentList(SingletonSeparatedList(IdentifierName("IProgressManager"))))
)
)
- }
- )
- );
+ ),
+ Argument(
+ MemberAccessExpression(
+ SyntaxKind.SimpleMemberAccessExpression,
+ responseName.EnsureNotNullable(),
+ IdentifierName("From")
+ )
+ )
+ }.Where(z => z is not null)
+ )!;
- private static ArgumentListSyntax GetPartialItemsArgumentList(TypeSyntax responseName, ArgumentSyntax handlerArgument) =>
+ private static ArgumentListSyntax GetPartialItemsArgumentList(
+ TypeSyntax responseName, ArgumentSyntax handlerArgument, ArgumentSyntax? initialArgument
+ ) =>
ArgumentList(
SeparatedList(
- new[] {
- handlerArgument,
- Argument(
- InvocationExpression(
+ new[]
+ {
+ initialArgument!,
+ handlerArgument,
+ Argument(
+ InvocationExpression(
+ MemberAccessExpression(
+ SyntaxKind.SimpleMemberAccessExpression,
+ IdentifierName("_"),
+ GenericName(Identifier("GetService"))
+ .WithTypeArgumentList(TypeArgumentList(SingletonSeparatedList(IdentifierName("IProgressManager"))))
+ )
+ )
+ ),
+ Argument(
MemberAccessExpression(
SyntaxKind.SimpleMemberAccessExpression,
- IdentifierName("_"),
- GenericName(Identifier("GetService"))
- .WithTypeArgumentList(TypeArgumentList(SingletonSeparatedList(IdentifierName("IProgressManager"))))
+ responseName.EnsureNotNullable(),
+ IdentifierName("From")
)
)
- ),
- Argument(
- MemberAccessExpression(
- SyntaxKind.SimpleMemberAccessExpression,
- responseName.EnsureNotNullable(),
- IdentifierName("From")
- )
- )
- }
+ }
+ .Where(z => z is not null)
)
);
@@ -456,7 +497,9 @@ public static ObjectCreationExpressionSyntax CreateHandlerArgument(NameSyntax cl
public static ObjectCreationExpressionSyntax CreateHandlerArgument(string innerClassName, params TypeSyntax[] genericArguments) =>
ObjectCreationExpression(GenericName(innerClassName).WithTypeArgumentList(TypeArgumentList(SeparatedList(genericArguments))));
- public static ArrowExpressionClauseSyntax GetNotificationCapabilityHandlerExpression(ExpressionSyntax nameExpression, TypeSyntax requestName, TypeSyntax capabilityName)
+ public static ArrowExpressionClauseSyntax GetNotificationCapabilityHandlerExpression(
+ ExpressionSyntax nameExpression, TypeSyntax requestName, TypeSyntax capabilityName
+ )
{
return ArrowExpressionClause(
AddHandler(
@@ -540,7 +583,7 @@ TypeSyntax capability
public static ArrowExpressionClauseSyntax GetPartialResultCapabilityHandlerExpression(
ExpressionSyntax nameExpression, TypeSyntax requestName, TypeSyntax itemType, TypeSyntax responseType,
- TypeSyntax capabilityName
+ TypeSyntax capabilityName, bool requestPartialHasInitialValue
)
{
return ArrowExpressionClause(
@@ -553,20 +596,30 @@ TypeSyntax capabilityName
),
CreateHandlerArgument(
IdentifierName("LanguageProtocolDelegatingHandlers"),
- "PartialResultCapability",
+ requestPartialHasInitialValue ? "PartialResultCapabilityWithInitialValue" : "PartialResultCapability",
requestName,
responseType,
itemType,
capabilityName
)
.WithArgumentList(
- GetPartialResultArgumentList(
- responseType,
- GetHandlerAdapterArgument(
- TypeArgumentList(SeparatedList(new[] { requestName, itemType })),
- HandlerArgument,
- capabilityName,
- true
+ ArgumentList(
+ GetPartialResultArgumentList(
+ responseType,
+ GetHandlerAdapterArgument(
+ TypeArgumentList(SeparatedList(new[] { requestName, itemType })),
+ HandlerArgument,
+ capabilityName,
+ true
+ ),
+ requestPartialHasInitialValue
+ ? GetHandlerAdapterArgument(
+ TypeArgumentList(SeparatedList(new[] { requestName, responseType })),
+ InitialHandlerArgument,
+ capabilityName,
+ false
+ )
+ : null
)
)
)
@@ -577,7 +630,7 @@ TypeSyntax capabilityName
}
public static ArrowExpressionClauseSyntax GetPartialResultHandlerExpression(
- ExpressionSyntax nameExpression, TypeSyntax requestName, TypeSyntax partialItem, TypeSyntax responseType
+ ExpressionSyntax nameExpression, TypeSyntax requestName, TypeSyntax partialItem, TypeSyntax responseType, bool requestPartialHasInitialValue
)
{
return ArrowExpressionClause(
@@ -590,12 +643,18 @@ public static ArrowExpressionClauseSyntax GetPartialResultHandlerExpression(
),
CreateHandlerArgument(
IdentifierName("LanguageProtocolDelegatingHandlers"),
- "PartialResult",
+ requestPartialHasInitialValue ? "PartialResultWithInitialValue" : "PartialResult",
requestName,
responseType,
partialItem
)
- .WithArgumentList(GetPartialResultArgumentList(responseType, HandlerArgument))
+ .WithArgumentList(
+ ArgumentList(
+ GetPartialResultArgumentList(
+ responseType, HandlerArgument, requestPartialHasInitialValue ? InitialHandlerArgument : null
+ )
+ )
+ )
)
)
)
@@ -604,7 +663,7 @@ public static ArrowExpressionClauseSyntax GetPartialResultHandlerExpression(
public static ArrowExpressionClauseSyntax GetPartialResultsCapabilityHandlerExpression(
ExpressionSyntax nameExpression, TypeSyntax requestName, TypeSyntax responseType,
- TypeSyntax itemName, TypeSyntax capabilityName
+ TypeSyntax itemName, TypeSyntax capabilityName, bool requestPartialHasInitialValue
)
{
return ArrowExpressionClause(
@@ -617,20 +676,30 @@ public static ArrowExpressionClauseSyntax GetPartialResultsCapabilityHandlerExpr
),
CreateHandlerArgument(
IdentifierName("LanguageProtocolDelegatingHandlers"),
- "PartialResultsCapability",
+ requestPartialHasInitialValue ? "PartialResultsCapabilityWithInitialValue" : "PartialResultsCapability",
requestName,
responseType,
itemName,
capabilityName
)
.WithArgumentList(
- GetPartialResultArgumentList(
- responseType,
- GetHandlerAdapterArgument(
- TypeArgumentList(SeparatedList(new[] { requestName, itemName })),
- HandlerArgument,
- capabilityName,
- true
+ ArgumentList(
+ GetPartialResultArgumentList(
+ responseType,
+ GetHandlerAdapterArgument(
+ TypeArgumentList(SeparatedList(new[] { requestName, itemName })),
+ HandlerArgument,
+ capabilityName,
+ true
+ ),
+ requestPartialHasInitialValue
+ ? GetHandlerAdapterArgument(
+ TypeArgumentList(SeparatedList(new[] { requestName, responseType })),
+ InitialHandlerArgument,
+ capabilityName,
+ false
+ )
+ : null
)
)
)
@@ -642,7 +711,7 @@ public static ArrowExpressionClauseSyntax GetPartialResultsCapabilityHandlerExpr
public static ArrowExpressionClauseSyntax GetPartialResultsHandlerExpression(
ExpressionSyntax nameExpression, TypeSyntax requestName, TypeSyntax itemName,
- TypeSyntax responseType
+ TypeSyntax responseType, bool requestPartialHasInitialValue
)
{
return ArrowExpressionClause(
@@ -655,7 +724,7 @@ TypeSyntax responseType
),
CreateHandlerArgument(
IdentifierName("LanguageProtocolDelegatingHandlers"),
- "PartialResults",
+ requestPartialHasInitialValue ? "PartialResultsWithInitialValue" : "PartialResults",
requestName,
responseType,
itemName
@@ -668,7 +737,15 @@ TypeSyntax responseType
HandlerArgument,
null,
true
- )
+ ),
+ requestPartialHasInitialValue
+ ? GetHandlerAdapterArgument(
+ TypeArgumentList(SeparatedList(new[] { requestName, responseType })),
+ InitialHandlerArgument,
+ null,
+ false
+ )
+ : null
)
)
)
@@ -689,7 +766,8 @@ public static ArrowExpressionClauseSyntax GetNotificationHandlerExpression(Expre
.WithArgumentList(
ArgumentList(
SeparatedList(
- new SyntaxNodeOrToken[] {
+ new SyntaxNodeOrToken[]
+ {
Argument(nameExpression),
Token(SyntaxKind.CommaToken),
Argument(
@@ -723,7 +801,8 @@ ExpressionSyntax nameExpression
.WithArgumentList(
ArgumentList(
SeparatedList(
- new[] {
+ new[]
+ {
Argument(nameExpression),
Argument(
item.IsUnit
@@ -773,7 +852,8 @@ public static ArrowExpressionClauseSyntax GetNotificationInvokeExpression() =>
.WithArgumentList(
ArgumentList(
SeparatedList(
- new[] {
+ new[]
+ {
Argument(IdentifierName(@"request"))
}
)
@@ -793,7 +873,8 @@ public static ArrowExpressionClauseSyntax GetRequestInvokeExpression() =>
.WithArgumentList(
ArgumentList(
SeparatedList(
- new[] {
+ new[]
+ {
Argument(IdentifierName(@"request")),
Argument(IdentifierName("cancellationToken"))
}
@@ -802,39 +883,70 @@ public static ArrowExpressionClauseSyntax GetRequestInvokeExpression() =>
)
);
- public static ArrowExpressionClauseSyntax GetPartialInvokeExpression(TypeSyntax responseType, TypeSyntax? partialItemType)
+ public static ArrowExpressionClauseSyntax GetRequestReturningInvokeExpression(ExpressionSyntax requestName, TypeSyntax responseType) =>
+ ArrowExpressionClause(
+ InvocationExpression(
+ MemberAccessExpression(
+ SyntaxKind.SimpleMemberAccessExpression,
+ InvocationExpression(
+ MemberAccessExpression(
+ SyntaxKind.SimpleMemberAccessExpression,
+ IdentifierName("client"),
+ IdentifierName("SendRequest")))
+ .WithArgumentList(
+ ArgumentList(
+ SeparatedList(
+ new []{
+ Argument(requestName),
+ Argument((IdentifierName(@"request")))}))),
+ GenericName(
+ Identifier("Returning"))
+ .WithTypeArgumentList(
+ TypeArgumentList(
+ SingletonSeparatedList(responseType)))))
+ .WithArgumentList(
+ ArgumentList(
+ SingletonSeparatedList(
+ Argument(
+ IdentifierName("cancellationToken")))))
+ );
+
+ public static ArrowExpressionClauseSyntax GetPartialInvokeExpression(
+ TypeSyntax responseType, TypeSyntax? partialItemType, bool partialItemTypeInheritsFromSelf
+ )
{
var realResponseType = responseType is NullableTypeSyntax nts ? nts.ElementType : responseType;
var factoryArgument = Argument(
- SimpleLambdaExpression(
- Parameter(Identifier("value")),
- ObjectCreationExpression(realResponseType)
- .WithArgumentList(ArgumentList(SingletonSeparatedList(Argument(IdentifierName("value")))))
+ MemberAccessExpression(
+ SyntaxKind.SimpleMemberAccessExpression,
+ realResponseType.EnsureNotNullable(),
+ IdentifierName("From")
)
);
- var arguments = new[] {
- Argument(
- IdentifierName(@"request")
- ),
+ var arguments = new[]
+ {
+ Argument(IdentifierName(@"request")),
factoryArgument,
Argument(IdentifierName("cancellationToken"))
};
- if (partialItemType is {})
+ if (partialItemType is { } && !partialItemTypeInheritsFromSelf)
{
var realPartialItemType = partialItemType is NullableTypeSyntax nts2 ? nts2.ElementType : partialItemType;
- arguments = new[] {
+ arguments = new[]
+ {
arguments[0],
arguments[1],
Argument(
- SimpleLambdaExpression(
- Parameter(Identifier("value")),
- ObjectCreationExpression(realPartialItemType)
- .WithArgumentList(ArgumentList(SingletonSeparatedList(Argument(IdentifierName("value")))))
+ MemberAccessExpression(
+ SyntaxKind.SimpleMemberAccessExpression,
+ realPartialItemType.EnsureNotNullable(),
+ IdentifierName("From")
)
),
arguments[2]
};
}
+
return ArrowExpressionClause(
InvocationExpression(
MemberAccessExpression(
@@ -893,14 +1005,17 @@ public static string SpecialCasedHandlerName(INamedTypeSymbol symbol)
}
public static SeparatedSyntaxList HandlerIdentityConstraint { get; } = SeparatedList(
- new TypeParameterConstraintSyntax[] {
+ new TypeParameterConstraintSyntax[]
+ {
ClassOrStructConstraint(SyntaxKind.ClassConstraint)
.WithQuestionToken(Token(SyntaxKind.QuestionToken)),
TypeConstraint(NullableType(IdentifierName("IHandlerIdentity"))),
}
);
- public static SyntaxList HandlerIdentityConstraintClause(bool withHandlerIdentity, IdentifierNameSyntax? openGenericType = null)
+ public static SyntaxList HandlerIdentityConstraintClause(
+ bool withHandlerIdentity, IdentifierNameSyntax? openGenericType = null
+ )
{
if (!withHandlerIdentity)
return SingletonList(
@@ -946,7 +1061,8 @@ public static class CommonElements
private static readonly Lazy GetSetAccessorLazy = LazyFactory.Create(
() => AccessorList(
List(
- new[] {
+ new[]
+ {
AccessorDeclaration(SyntaxKind.GetAccessorDeclaration).WithSemicolonToken(Token(SyntaxKind.SemicolonToken)),
AccessorDeclaration(SyntaxKind.SetAccessorDeclaration).WithSemicolonToken(Token(SyntaxKind.SemicolonToken))
}
@@ -957,7 +1073,8 @@ public static class CommonElements
private static readonly Lazy GetInitAccessorLazy = LazyFactory.Create(
() => AccessorList(
List(
- new[] {
+ new[]
+ {
AccessorDeclaration(SyntaxKind.GetAccessorDeclaration)
.WithSemicolonToken(Token(SyntaxKind.SemicolonToken)),
AccessorDeclaration(SyntaxKind.InitAccessorDeclaration)
@@ -972,7 +1089,8 @@ public static class CommonElements
private static readonly Lazy GetAccessorLazy = LazyFactory.Create(
() => AccessorList(
List(
- new[] {
+ new[]
+ {
AccessorDeclaration(SyntaxKind.GetAccessorDeclaration).WithSemicolonToken(Token(SyntaxKind.SemicolonToken))
}
)
@@ -989,7 +1107,8 @@ public static class SyntaxExtensions
public static string? GetSyntaxName(this TypeSyntax typeSyntax)
{
- return typeSyntax switch {
+ return typeSyntax switch
+ {
SimpleNameSyntax sns => sns.Identifier.Text,
QualifiedNameSyntax qns => qns.Right.Identifier.Text,
NullableTypeSyntax nts => nts.ElementType.GetSyntaxName() + "?",
@@ -1091,19 +1210,25 @@ public static BaseMethodDeclarationSyntax MakeMethodNullable(this BaseMethodDecl
if (syntax.ExpressionBody is not null)
{
- syntax = syntax.WithExpressionBody(syntax.ExpressionBody.WithExpression(syntax.ExpressionBody.Expression.InsideNullableSwitchExpression(identifierNameSyntax)));
+ syntax = syntax.WithExpressionBody(
+ syntax.ExpressionBody.WithExpression(syntax.ExpressionBody.Expression.InsideNullableSwitchExpression(identifierNameSyntax))
+ );
}
return syntax
.WithParameterList(
- ParameterList(SeparatedList(syntax.ParameterList.Parameters.Select(parameter => parameter.WithType(parameter.Type?.EnsureNullable())).ToArray()))
+ ParameterList(
+ SeparatedList(syntax.ParameterList.Parameters.Select(parameter => parameter.WithType(parameter.Type?.EnsureNullable())).ToArray())
+ )
)
.AddAttributeLists(
AttributeList(
SingletonSeparatedList(
Attribute(
QualifiedName(
- QualifiedName(QualifiedName(IdentifierName("System"), IdentifierName("Diagnostics")), IdentifierName("CodeAnalysis")),
+ QualifiedName(
+ QualifiedName(IdentifierName("System"), IdentifierName("Diagnostics")), IdentifierName("CodeAnalysis")
+ ),
IdentifierName("NotNullIfNotNull")
)
)
@@ -1130,7 +1255,9 @@ public static MethodDeclarationSyntax MakeMethodNullable(this MethodDeclarationS
return ( MakeMethodNullable(syntax as BaseMethodDeclarationSyntax, identifierNameSyntax) as MethodDeclarationSyntax )!;
}
- public static ConversionOperatorDeclarationSyntax MakeMethodNullable(this ConversionOperatorDeclarationSyntax syntax, IdentifierNameSyntax identifierNameSyntax)
+ public static ConversionOperatorDeclarationSyntax MakeMethodNullable(
+ this ConversionOperatorDeclarationSyntax syntax, IdentifierNameSyntax identifierNameSyntax
+ )
{
return ( MakeMethodNullable(syntax as BaseMethodDeclarationSyntax, identifierNameSyntax) as ConversionOperatorDeclarationSyntax )!;
}
@@ -1140,7 +1267,8 @@ public static SwitchExpressionSyntax InsideNullableSwitchExpression(this Express
return SwitchExpression(name)
.WithArms(
SeparatedList(
- new[] {
+ new[]
+ {
SwitchExpressionArm(
UnaryPattern(ConstantPattern(LiteralExpression(SyntaxKind.NullLiteralExpression))),
creationExpression
diff --git a/src/JsonRpc.Generators/RegistrationOptionsGenerator.cs b/src/JsonRpc.Generators/RegistrationOptionsGenerator.cs
index 2c36fcf4f..fc3bfddf8 100644
--- a/src/JsonRpc.Generators/RegistrationOptionsGenerator.cs
+++ b/src/JsonRpc.Generators/RegistrationOptionsGenerator.cs
@@ -23,8 +23,11 @@ public class RegistrationOptionsGenerator : IIncrementalGenerator
};
private record AttributeData(
- INamedTypeSymbol RegistrationOptionsInterfaceSymbol, INamedTypeSymbol TextDocumentRegistrationOptionsInterfaceSymbol,
- INamedTypeSymbol WorkDoneProgressOptionsInterfaceSymbol, INamedTypeSymbol StaticRegistrationOptionsInterfaceSymbol
+ INamedTypeSymbol RegistrationOptionsInterfaceSymbol,
+ INamedTypeSymbol TextDocumentRegistrationOptionsInterfaceSymbol,
+ INamedTypeSymbol NotebookDocumentRegistrationOptionsInterfaceSymbol,
+ INamedTypeSymbol WorkDoneProgressOptionsInterfaceSymbol,
+ INamedTypeSymbol StaticRegistrationOptionsInterfaceSymbol
);
public void Initialize(IncrementalGeneratorInitializationContext context)
@@ -39,6 +42,10 @@ public void Initialize(IncrementalGeneratorInitializationContext context)
compilation.GetTypeByMetadataName(
"OmniSharp.Extensions.LanguageServer.Protocol.Models.ITextDocumentRegistrationOptions"
)!;
+ var notebookDocumentRegistrationOptionsInterfaceSymbol =
+ compilation.GetTypeByMetadataName(
+ "OmniSharp.Extensions.LanguageServer.Protocol.Models.INotebookDocumentRegistrationOptions"
+ )!;
var workDoneProgressOptionsInterfaceSymbol =
compilation.GetTypeByMetadataName(
"OmniSharp.Extensions.LanguageServer.Protocol.Models.IWorkDoneProgressOptions"
@@ -48,8 +55,11 @@ public void Initialize(IncrementalGeneratorInitializationContext context)
"OmniSharp.Extensions.LanguageServer.Protocol.Models.IStaticRegistrationOptions"
)!;
return new AttributeData(
- registrationOptionsInterfaceSymbol, textDocumentRegistrationOptionsInterfaceSymbol,
- workDoneProgressOptionsInterfaceSymbol, staticRegistrationOptionsInterfaceSymbol
+ registrationOptionsInterfaceSymbol,
+ textDocumentRegistrationOptionsInterfaceSymbol,
+ notebookDocumentRegistrationOptionsInterfaceSymbol,
+ workDoneProgressOptionsInterfaceSymbol,
+ staticRegistrationOptionsInterfaceSymbol
);
}
);
@@ -162,7 +172,7 @@ private void GenerateRegistrationOptions(
staticRegistrationOptions = staticRegistrationOptions.AddAttributeLists(attributeList);
}
- if (data.SupportsDocumentSelector && !data.ImplementsDocumentSelector)
+ if (data.SupportsTextDocumentSelector && !data.ImplementsTextDocumentSelector)
{
if (registrationOptions.BaseList?.Types.Any(
z => z.Type.ToFullString().Contains(attributes.TextDocumentRegistrationOptionsInterfaceSymbol.Name)
@@ -174,7 +184,37 @@ private void GenerateRegistrationOptions(
}
extendedRegistrationOptions = extendedRegistrationOptions.AddMembers(
- PropertyDeclaration(NullableType(IdentifierName("DocumentSelector")), Identifier("DocumentSelector"))
+ PropertyDeclaration(NullableType(IdentifierName("TextDocumentSelector")), Identifier("DocumentSelector"))
+ .WithModifiers(TokenList(Token(SyntaxKind.PublicKeyword)))
+ .WithAccessorList(
+ AccessorList(
+ List(
+ new[]
+ {
+ AccessorDeclaration(SyntaxKind.GetAccessorDeclaration)
+ .WithSemicolonToken(Token(SyntaxKind.SemicolonToken)),
+ AccessorDeclaration(SyntaxKind.SetAccessorDeclaration)
+ .WithSemicolonToken(Token(SyntaxKind.SemicolonToken))
+ }
+ )
+ )
+ )
+ );
+ }
+
+ if (data.SupportsNotebookDocumentSelector && !data.ImplementsNotebookDocumentSelector)
+ {
+ if (registrationOptions.BaseList?.Types.Any(
+ z => z.Type.ToFullString().Contains(attributes.NotebookDocumentRegistrationOptionsInterfaceSymbol.Name)
+ ) != true)
+ {
+ extendedRegistrationOptions = ExtendAndImplementInterface(
+ extendedRegistrationOptions, attributes.NotebookDocumentRegistrationOptionsInterfaceSymbol
+ );
+ }
+
+ extendedRegistrationOptions = extendedRegistrationOptions.AddMembers(
+ PropertyDeclaration(NullableType(IdentifierName("NotebookDocumentSelector")), Identifier("DocumentSelector"))
.WithModifiers(TokenList(Token(SyntaxKind.PublicKeyword)))
.WithAccessorList(
AccessorList(
@@ -272,7 +312,7 @@ private void GenerateRegistrationOptions(
catch (Exception e)
{
context.ReportDiagnostic(
- Diagnostic.Create(GeneratorDiagnostics.Exception, registrationOptions.GetLocation(), e.Message, e.StackTrace ?? string.Empty)
+ Diagnostic.Create(GeneratorDiagnostics.Exception, registrationOptions.GetLocation(), e.Message, e.StackTrace?.Replace("\n", " ") ?? string.Empty, e.ToString())
);
Debug.WriteLine(e);
Debug.WriteLine(e.StackTrace);
diff --git a/src/JsonRpc.Generators/Strategies/HandlerGeneratorStrategy.cs b/src/JsonRpc.Generators/Strategies/HandlerGeneratorStrategy.cs
index 08a0b1368..b96ee20c0 100644
--- a/src/JsonRpc.Generators/Strategies/HandlerGeneratorStrategy.cs
+++ b/src/JsonRpc.Generators/Strategies/HandlerGeneratorStrategy.cs
@@ -260,6 +260,30 @@ public IEnumerable Apply(SourceProductionContext contex
}
members.Add(handlerClass);
+
+ if (resolver is { LspAttributes: { GenerateTypedData: true } })
+ {
+ members.Add(
+ GenerateTypedPartialItemHandler(
+ handlerClass,
+ request,
+ resolver,
+ request.PartialItem
+ )
+ );
+ }
+
+ if (request is { LspAttributes: { GenerateTypedData: true } })
+ {
+ members.Add(
+ GenerateTypedPartialItemHandler(
+ handlerClass,
+ request,
+ request,
+ request.PartialItem
+ )
+ );
+ }
}
else if (request is { PartialItems: { } partialItems })
{
@@ -297,7 +321,7 @@ public IEnumerable Apply(SourceProductionContext contex
if (resolver is { LspAttributes: { GenerateTypedData: true } })
{
members.Add(
- GenerateTypedPartialHandler(
+ GenerateTypedPartialItemsHandler(
handlerClass,
request,
resolver,
@@ -309,7 +333,7 @@ public IEnumerable Apply(SourceProductionContext contex
if (request is { LspAttributes: { GenerateTypedData: true } })
{
members.Add(
- GenerateTypedPartialHandler(
+ GenerateTypedPartialItemsHandler(
handlerClass,
request,
request,
@@ -401,7 +425,7 @@ private static TypeSyntax GetPartialResultBaseClass(RequestItem request, SyntaxS
return QualifiedName(
IdentifierName("AbstractHandlers"),
- GenericName($"PartialResult{( onlyCapability ? "Capability" : "" )}")
+ GenericName($"PartialResult{( request.PartialHasInitialValue ? "WithInitialValue" : "" )}{( onlyCapability ? "Capability" : "" )}")
.WithTypeArgumentList(TypeArgumentList(SeparatedList(types)))
);
}
@@ -423,7 +447,7 @@ private static TypeSyntax GetPartialResultsBaseClass(RequestItem request, Syntax
return QualifiedName(
IdentifierName("AbstractHandlers"),
- GenericName($"PartialResults{( onlyCapability ? "Capability" : "" )}")
+ GenericName($"PartialResults{( request.PartialHasInitialValue ? "WithInitialValue" : "" )}{( onlyCapability ? "Capability" : "" )}")
.WithTypeArgumentList(TypeArgumentList(SeparatedList(types)))
);
}
@@ -597,11 +621,11 @@ private static IEnumerable AddConstructors(RequestItem
}
}
- private static TypeDeclarationSyntax GenerateTypedPartialHandler(
+ private static TypeDeclarationSyntax GenerateTypedPartialItemHandler(
TypeDeclarationSyntax classDeclarationSyntax,
RequestItem item,
RequestItem resolver,
- SyntaxSymbol partialItems
+ SyntaxSymbol partialItem
)
{
return ClassDeclaration(classDeclarationSyntax.Identifier)
@@ -673,13 +697,8 @@ SyntaxSymbol partialItems
GenericName(Identifier("IObserver"))
.WithTypeArgumentList(
TypeArgumentList(
- SingletonSeparatedList(
- GenericName(Identifier("IEnumerable"))
- .WithTypeArgumentList(TypeArgumentList(SingletonSeparatedList(partialItems.Syntax)))
- )
- )
- )
- ),
+ SingletonSeparatedList(partialItem.Syntax)))
+ ),
Parameter(Identifier("cancellationToken")).WithType(IdentifierName("CancellationToken"))
}
)
@@ -712,7 +731,7 @@ SyntaxSymbol partialItems
)
)
),
- partialItems.Syntax
+ partialItem.Syntax
}
)
)
@@ -729,7 +748,7 @@ SyntaxSymbol partialItems
Argument(
MemberAccessExpression(
SyntaxKind.SimpleMemberAccessExpression,
- partialItems.Syntax,
+ partialItem.Syntax,
IdentifierName("From")
)
)
@@ -831,10 +850,6 @@ SyntaxSymbol partialItems
.WithTypeArgumentList(
TypeArgumentList(
SingletonSeparatedList(
- GenericName(Identifier("IEnumerable"))
- .WithTypeArgumentList(
- TypeArgumentList(
- SingletonSeparatedList(
GenericName(Identifier(resolver.Request.Symbol.Name))
.WithTypeArgumentList(
TypeArgumentList(
@@ -843,9 +858,6 @@ SyntaxSymbol partialItems
)
)
)
- )
- )
- )
)
)
)
@@ -899,21 +911,14 @@ SyntaxSymbol partialItems
);
}
- private static TypeDeclarationSyntax GenerateTypedHandler(
+
+ private static TypeDeclarationSyntax GenerateTypedPartialItemsHandler(
TypeDeclarationSyntax classDeclarationSyntax,
RequestItem item,
- RequestItem resolver
+ RequestItem resolver,
+ SyntaxSymbol partialItems
)
{
- TypeSyntax responseType = GenericName(Identifier(item.Response.Symbol.Name))
- .WithTypeArgumentList(TypeArgumentList(SingletonSeparatedList(IdentifierName("T"))));
- // Special case... because the spec is awesome
- if (item.Response.Symbol.Name == "CommandOrCodeActionContainer")
- {
- responseType = GenericName(Identifier("CodeActionContainer"))
- .WithTypeArgumentList(TypeArgumentList(SingletonSeparatedList(IdentifierName("T"))));
- }
-
return ClassDeclaration(classDeclarationSyntax.Identifier)
.WithModifiers(classDeclarationSyntax.Modifiers)
.WithAttributeLists(classDeclarationSyntax.AttributeLists)
@@ -922,45 +927,74 @@ RequestItem resolver
.AddMembers(
ConstructorDeclaration(classDeclarationSyntax.Identifier)
.WithModifiers(TokenList(Token(SyntaxKind.ProtectedKeyword)))
- .WithParameterList(ParameterList(SingletonSeparatedList(Parameter(Identifier("id")).WithType(IdentifierName("Guid")))))
+ .WithParameterList(
+ ParameterList(
+ SeparatedList(
+ new[] {
+ Parameter(Identifier("id")).WithType(IdentifierName("Guid")),
+ Parameter(Identifier("progressManager")).WithType(IdentifierName("IProgressManager"))
+ }
+ )
+ )
+ )
.WithInitializer(
ConstructorInitializer(
SyntaxKind.BaseConstructorInitializer,
- ArgumentList(SingletonSeparatedList(Argument(IdentifierName("id"))))
+ ArgumentList(
+ SeparatedList(
+ new[] {
+ Argument(IdentifierName("id")),
+ Argument(
+ IdentifierName("progressManager")
+ )
+ }
+ )
+ )
)
)
.WithBody(Block()),
ConstructorDeclaration(classDeclarationSyntax.Identifier)
.WithModifiers(TokenList(Token(SyntaxKind.ProtectedKeyword)))
+ .WithParameterList(ParameterList(SingletonSeparatedList(Parameter(Identifier("progressManager")).WithType(IdentifierName("IProgressManager")))))
.WithInitializer(
ConstructorInitializer(
SyntaxKind.ThisConstructorInitializer,
ArgumentList(
- SingletonSeparatedList(
- Argument(
- InvocationExpression(
- MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, IdentifierName("Guid"), IdentifierName("NewGuid"))
+ SeparatedList(
+ new[] {
+ Argument(
+ InvocationExpression(
+ MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, IdentifierName("Guid"), IdentifierName("NewGuid"))
+ )
+ ),
+ Argument(
+ IdentifierName("progressManager")
)
- )
+ }
)
)
)
)
.WithBody(Block()),
- MethodDeclaration(
- GenericName(Identifier("Task")).WithTypeArgumentList(TypeArgumentList(SingletonSeparatedList(item.Response.Syntax))),
- Identifier("Handle")
- )
- .WithModifiers(
- TokenList(
- Token(SyntaxKind.PublicKeyword), Token(SyntaxKind.SealedKeyword), Token(SyntaxKind.OverrideKeyword), Token(SyntaxKind.AsyncKeyword)
- )
- )
+ MethodDeclaration(PredefinedType(Token(SyntaxKind.VoidKeyword)), Identifier("Handle"))
+ .WithModifiers(TokenList(Token(SyntaxKind.ProtectedKeyword), Token(SyntaxKind.SealedKeyword), Token(SyntaxKind.OverrideKeyword)))
.WithParameterList(
ParameterList(
SeparatedList(
new[] {
Parameter(Identifier("request")).WithType(item.Request.Syntax),
+ Parameter(Identifier("results"))
+ .WithType(
+ GenericName(Identifier("IObserver"))
+ .WithTypeArgumentList(
+ TypeArgumentList(
+ SingletonSeparatedList(
+ GenericName(Identifier("IEnumerable"))
+ .WithTypeArgumentList(TypeArgumentList(SingletonSeparatedList(partialItems.Syntax)))
+ )
+ )
+ )
+ ),
Parameter(Identifier("cancellationToken")).WithType(IdentifierName("CancellationToken"))
}
)
@@ -968,101 +1002,137 @@ RequestItem resolver
)
.WithExpressionBody(
ArrowExpressionClause(
- AwaitExpression(
- InvocationExpression(
- MemberAccessExpression(
- SyntaxKind.SimpleMemberAccessExpression,
- InvocationExpression(IdentifierName("HandleParams"))
- .WithArgumentList(
- ArgumentList(
- SeparatedList(
- new[] {
- Argument(IdentifierName("request")),
- Argument(IdentifierName("cancellationToken"))
- }
+ InvocationExpression(IdentifierName("Handle"))
+ .WithArgumentList(
+ ArgumentList(
+ SeparatedList(
+ new[] {
+ Argument(IdentifierName("request")),
+ Argument(
+ ObjectCreationExpression(
+ QualifiedName(
+ IdentifierName("LanguageProtocolDelegatingHandlers"),
+ GenericName(
+ Identifier("TypedPartialObserver")
+ )
+ .WithTypeArgumentList(
+ TypeArgumentList(
+ SeparatedList(
+ new[] {
+ GenericName(Identifier(resolver.Response.Symbol.Name))
+ .WithTypeArgumentList(
+ TypeArgumentList(
+ SingletonSeparatedList(
+ IdentifierName("T")
+ )
+ )
+ ),
+ partialItems.Syntax
+ }
+ )
+ )
+ )
+ )
+ )
+ .WithArgumentList(
+ ArgumentList(
+ SeparatedList(
+ new[] {
+ Argument(
+ IdentifierName("results")
+ ),
+ Argument(
+ MemberAccessExpression(
+ SyntaxKind.SimpleMemberAccessExpression,
+ partialItems.Syntax,
+ IdentifierName("From")
+ )
+ )
+ }
+ )
+ )
)
- )
),
- IdentifierName("ConfigureAwait")
- )
- )
- .WithArgumentList(
- ArgumentList(
- SingletonSeparatedList(
- Argument(
- LiteralExpression(
- SyntaxKind.FalseLiteralExpression
- )
- )
- )
+ Argument(IdentifierName("cancellationToken"))
+ }
)
)
- )
+ )
)
)
.WithSemicolonToken(Token(SyntaxKind.SemicolonToken)),
MethodDeclaration(
- GenericName(Identifier("Task")).WithTypeArgumentList(TypeArgumentList(SingletonSeparatedList(resolver.Response.Syntax))),
+ GenericName(Identifier("Task"))
+ .WithTypeArgumentList(
+ TypeArgumentList(
+ SingletonSeparatedList(
+ resolver.Response.Syntax
+ )
+ )
+ ),
Identifier("Handle")
)
.WithModifiers(
- TokenList(
- Token(SyntaxKind.PublicKeyword), Token(SyntaxKind.SealedKeyword), Token(SyntaxKind.OverrideKeyword), Token(SyntaxKind.AsyncKeyword)
- )
+ TokenList(Token(SyntaxKind.PublicKeyword), Token(SyntaxKind.SealedKeyword), Token(SyntaxKind.OverrideKeyword), Token(SyntaxKind.AsyncKeyword))
)
.WithParameterList(
ParameterList(
SeparatedList(
new[] {
- Parameter(Identifier("request")).WithType(resolver.Response.Syntax),
+ Parameter(Identifier("request")).WithType(resolver.Request.Syntax),
Parameter(Identifier("cancellationToken")).WithType(IdentifierName("CancellationToken"))
}
)
)
)
- .WithExpressionBody(
- ArrowExpressionClause(
- AwaitExpression(
- InvocationExpression(
- MemberAccessExpression(
- SyntaxKind.SimpleMemberAccessExpression,
- InvocationExpression(IdentifierName("HandleResolve"))
- .WithArgumentList(
- ArgumentList(
- SeparatedList(
- new[] {
- Argument(
- IdentifierName("request")
- ),
- Argument(
- IdentifierName("cancellationToken")
+ .WithBody(
+ Block(
+ LocalDeclarationStatement(
+ VariableDeclaration(IdentifierName("var"))
+ .WithVariables(
+ SingletonSeparatedList(
+ VariableDeclarator(Identifier("response"))
+ .WithInitializer(
+ EqualsValueClause(
+ AwaitExpression(
+ InvocationExpression(
+ MemberAccessExpression(
+ SyntaxKind.SimpleMemberAccessExpression,
+ InvocationExpression(
+ IdentifierName("HandleResolve")
+ )
+ .WithArgumentList(
+ ArgumentList(
+ SeparatedList(
+ new[] {
+ Argument(IdentifierName("request")),
+ Argument(
+ IdentifierName("cancellationToken")
+ )
+ }
+ )
+ )
+ ),
+ IdentifierName("ConfigureAwait")
+ )
+ )
+ .WithArgumentList(
+ ArgumentList(
+ SingletonSeparatedList(Argument(LiteralExpression(SyntaxKind.FalseLiteralExpression)))
+ )
)
- }
)
)
- ),
- IdentifierName("ConfigureAwait")
- )
- )
- .WithArgumentList(
- ArgumentList(
- SingletonSeparatedList(
- Argument(
- LiteralExpression(
- SyntaxKind.FalseLiteralExpression
- )
)
- )
)
)
- )
+ ),
+ ReturnStatement(IdentifierName("response"))
)
- )
- .WithSemicolonToken(Token(SyntaxKind.SemicolonToken)),
+ ),
MethodDeclaration(
- GenericName(Identifier("Task"))
- .WithTypeArgumentList(TypeArgumentList(SingletonSeparatedList(responseType))),
- Identifier("HandleParams")
+ PredefinedType(Token(SyntaxKind.VoidKeyword)),
+ Identifier("Handle")
)
.WithModifiers(TokenList(Token(SyntaxKind.ProtectedKeyword), Token(SyntaxKind.AbstractKeyword)))
.WithParameterList(
@@ -1070,21 +1140,50 @@ RequestItem resolver
SeparatedList(
new[] {
Parameter(Identifier("request")).WithType(item.Request.Syntax),
+ Parameter(Identifier("results"))
+ .WithType(
+ GenericName(Identifier("IObserver"))
+ .WithTypeArgumentList(
+ TypeArgumentList(
+ SingletonSeparatedList(
+ GenericName(Identifier("IEnumerable"))
+ .WithTypeArgumentList(
+ TypeArgumentList(
+ SingletonSeparatedList(
+ GenericName(Identifier(resolver.Request.Symbol.Name))
+ .WithTypeArgumentList(
+ TypeArgumentList(
+ SingletonSeparatedList(
+ IdentifierName("T")
+ )
+ )
+ )
+ )
+ )
+ )
+ )
+ )
+ )
+ ),
Parameter(Identifier("cancellationToken")).WithType(IdentifierName("CancellationToken"))
}
)
)
)
- .WithSemicolonToken(
- Token(SyntaxKind.SemicolonToken)
- ),
+ .WithSemicolonToken(Token(SyntaxKind.SemicolonToken)),
MethodDeclaration(
GenericName(Identifier("Task"))
.WithTypeArgumentList(
TypeArgumentList(
SingletonSeparatedList(
- GenericName(Identifier(resolver.Response.Symbol.Name))
- .WithTypeArgumentList(TypeArgumentList(SingletonSeparatedList(IdentifierName("T"))))
+ GenericName(Identifier(resolver.Request.Symbol.Name))
+ .WithTypeArgumentList(
+ TypeArgumentList(
+ SingletonSeparatedList(
+ IdentifierName("T")
+ )
+ )
+ )
)
)
),
@@ -1097,9 +1196,14 @@ RequestItem resolver
new[] {
Parameter(Identifier("request"))
.WithType(
- GenericName(Identifier(resolver.Response.Symbol.Name)).WithTypeArgumentList(
- TypeArgumentList(SingletonSeparatedList(IdentifierName("T")))
- )
+ GenericName(Identifier(resolver.Request.Symbol.Name))
+ .WithTypeArgumentList(
+ TypeArgumentList(
+ SingletonSeparatedList(
+ IdentifierName("T")
+ )
+ )
+ )
),
Parameter(Identifier("cancellationToken")).WithType(IdentifierName("CancellationToken"))
}
@@ -1109,5 +1213,217 @@ RequestItem resolver
.WithSemicolonToken(Token(SyntaxKind.SemicolonToken))
);
}
+
+ private static TypeDeclarationSyntax GenerateTypedHandler(
+ TypeDeclarationSyntax classDeclarationSyntax,
+ RequestItem item,
+ RequestItem resolver
+ )
+ {
+ TypeSyntax responseType = GenericName(Identifier(item.Response.Symbol.Name))
+ .WithTypeArgumentList(TypeArgumentList(SingletonSeparatedList(IdentifierName("T"))));
+ // Special case... because the spec is awesome
+ if (item.Response.Symbol.Name == "CommandOrCodeActionContainer")
+ {
+ responseType = GenericName(Identifier("CodeActionContainer"))
+ .WithTypeArgumentList(TypeArgumentList(SingletonSeparatedList(IdentifierName("T"))));
+ }
+
+ var typeDeclarationSyntax = ClassDeclaration(classDeclarationSyntax.Identifier)
+ .WithModifiers(classDeclarationSyntax.Modifiers)
+ .WithAttributeLists(classDeclarationSyntax.AttributeLists)
+ .WithHandlerIdentityConstraint(true)
+ .WithBaseList(BaseList(SingletonSeparatedList(SimpleBaseType(IdentifierName(classDeclarationSyntax.Identifier.Text)))))
+ .AddMembers(
+ ConstructorDeclaration(classDeclarationSyntax.Identifier)
+ .WithModifiers(TokenList(Token(SyntaxKind.ProtectedKeyword)))
+ .WithParameterList(ParameterList(SingletonSeparatedList(Parameter(Identifier("id")).WithType(IdentifierName("Guid")))))
+ .WithInitializer(
+ ConstructorInitializer(
+ SyntaxKind.BaseConstructorInitializer,
+ ArgumentList(SingletonSeparatedList(Argument(IdentifierName("id"))))
+ )
+ )
+ .WithBody(Block()),
+ ConstructorDeclaration(classDeclarationSyntax.Identifier)
+ .WithModifiers(TokenList(Token(SyntaxKind.ProtectedKeyword)))
+ .WithInitializer(
+ ConstructorInitializer(
+ SyntaxKind.ThisConstructorInitializer,
+ ArgumentList(
+ SingletonSeparatedList(
+ Argument(
+ InvocationExpression(
+ MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, IdentifierName("Guid"), IdentifierName("NewGuid"))
+ )
+ )
+ )
+ )
+ )
+ )
+ .WithBody(Block()),
+ MethodDeclaration(
+ GenericName(Identifier("Task")).WithTypeArgumentList(TypeArgumentList(SingletonSeparatedList(item.Response.Syntax))),
+ Identifier("Handle")
+ )
+ .WithModifiers(
+ TokenList(
+ Token(SyntaxKind.PublicKeyword), Token(SyntaxKind.SealedKeyword), Token(SyntaxKind.OverrideKeyword), Token(SyntaxKind.AsyncKeyword)
+ )
+ )
+ .WithParameterList(
+ ParameterList(
+ SeparatedList(
+ new[] {
+ Parameter(Identifier("request")).WithType(item.Request.Syntax),
+ Parameter(Identifier("cancellationToken")).WithType(IdentifierName("CancellationToken"))
+ }
+ )
+ )
+ )
+ .WithExpressionBody(
+ ArrowExpressionClause(
+ AwaitExpression(
+ InvocationExpression(
+ MemberAccessExpression(
+ SyntaxKind.SimpleMemberAccessExpression,
+ InvocationExpression(IdentifierName("HandleParams"))
+ .WithArgumentList(
+ ArgumentList(
+ SeparatedList(
+ new[] {
+ Argument(IdentifierName("request")),
+ Argument(IdentifierName("cancellationToken"))
+ }
+ )
+ )
+ ),
+ IdentifierName("ConfigureAwait")
+ )
+ )
+ .WithArgumentList(
+ ArgumentList(
+ SingletonSeparatedList(
+ Argument(
+ LiteralExpression(
+ SyntaxKind.FalseLiteralExpression
+ )
+ )
+ )
+ )
+ )
+ )
+ )
+ )
+ .WithSemicolonToken(Token(SyntaxKind.SemicolonToken)),
+ MethodDeclaration(
+ GenericName(Identifier("Task")).WithTypeArgumentList(TypeArgumentList(SingletonSeparatedList(resolver.Response.Syntax))),
+ Identifier("Handle")
+ )
+ .WithModifiers(
+ TokenList(
+ Token(SyntaxKind.PublicKeyword), Token(SyntaxKind.SealedKeyword), Token(SyntaxKind.OverrideKeyword), Token(SyntaxKind.AsyncKeyword)
+ )
+ )
+ .WithParameterList(
+ ParameterList(
+ SeparatedList(
+ new[] {
+ Parameter(Identifier("request")).WithType(resolver.Response.Syntax),
+ Parameter(Identifier("cancellationToken")).WithType(IdentifierName("CancellationToken"))
+ }
+ )
+ )
+ )
+ .WithExpressionBody(
+ ArrowExpressionClause(
+ AwaitExpression(
+ InvocationExpression(
+ MemberAccessExpression(
+ SyntaxKind.SimpleMemberAccessExpression,
+ InvocationExpression(IdentifierName("HandleResolve"))
+ .WithArgumentList(
+ ArgumentList(
+ SeparatedList(
+ new[] {
+ Argument(
+ IdentifierName("request")
+ ),
+ Argument(
+ IdentifierName("cancellationToken")
+ )
+ }
+ )
+ )
+ ),
+ IdentifierName("ConfigureAwait")
+ )
+ )
+ .WithArgumentList(
+ ArgumentList(
+ SingletonSeparatedList(
+ Argument(
+ LiteralExpression(
+ SyntaxKind.FalseLiteralExpression
+ )
+ )
+ )
+ )
+ )
+ )
+ )
+ )
+ .WithSemicolonToken(Token(SyntaxKind.SemicolonToken)),
+ MethodDeclaration(
+ GenericName(Identifier("Task"))
+ .WithTypeArgumentList(TypeArgumentList(SingletonSeparatedList(responseType))),
+ Identifier("HandleParams")
+ )
+ .WithModifiers(TokenList(Token(SyntaxKind.ProtectedKeyword), Token(SyntaxKind.AbstractKeyword)))
+ .WithParameterList(
+ ParameterList(
+ SeparatedList(
+ new[] {
+ Parameter(Identifier("request")).WithType(item.Request.Syntax),
+ Parameter(Identifier("cancellationToken")).WithType(IdentifierName("CancellationToken"))
+ }
+ )
+ )
+ )
+ .WithSemicolonToken(
+ Token(SyntaxKind.SemicolonToken)
+ ),
+ MethodDeclaration(
+ GenericName(Identifier("Task"))
+ .WithTypeArgumentList(
+ TypeArgumentList(
+ SingletonSeparatedList(
+ GenericName(Identifier(resolver.Response.Symbol.Name))
+ .WithTypeArgumentList(TypeArgumentList(SingletonSeparatedList(IdentifierName("T"))))
+ )
+ )
+ ),
+ Identifier("HandleResolve")
+ )
+ .WithModifiers(TokenList(Token(SyntaxKind.ProtectedKeyword), Token(SyntaxKind.AbstractKeyword)))
+ .WithParameterList(
+ ParameterList(
+ SeparatedList(
+ new[] {
+ Parameter(Identifier("request"))
+ .WithType(
+ GenericName(Identifier(resolver.Response.Symbol.Name)).WithTypeArgumentList(
+ TypeArgumentList(SingletonSeparatedList(IdentifierName("T")))
+ )
+ ),
+ Parameter(Identifier("cancellationToken")).WithType(IdentifierName("CancellationToken"))
+ }
+ )
+ )
+ )
+ .WithSemicolonToken(Token(SyntaxKind.SemicolonToken))
+ );
+ return typeDeclarationSyntax;
+ }
}
}
diff --git a/src/JsonRpc.Generators/Strategies/OnNotificationMethodGeneratorWithRegistrationOptionsStrategy.cs b/src/JsonRpc.Generators/Strategies/OnNotificationMethodGeneratorWithRegistrationOptionsStrategy.cs
index b4f0324bc..925d615b3 100644
--- a/src/JsonRpc.Generators/Strategies/OnNotificationMethodGeneratorWithRegistrationOptionsStrategy.cs
+++ b/src/JsonRpc.Generators/Strategies/OnNotificationMethodGeneratorWithRegistrationOptionsStrategy.cs
@@ -138,6 +138,7 @@ private static BlockSyntax GetNotificationRegistrationHandlerExpression(
capabilityName,
false
),
+ null,
capabilityName,
false
)
diff --git a/src/JsonRpc.Generators/Strategies/OnRequestMethodGeneratorWithRegistrationOptionsStrategy.cs b/src/JsonRpc.Generators/Strategies/OnRequestMethodGeneratorWithRegistrationOptionsStrategy.cs
index 7ad741a03..b369106b4 100644
--- a/src/JsonRpc.Generators/Strategies/OnRequestMethodGeneratorWithRegistrationOptionsStrategy.cs
+++ b/src/JsonRpc.Generators/Strategies/OnRequestMethodGeneratorWithRegistrationOptionsStrategy.cs
@@ -44,9 +44,9 @@ public IEnumerable Apply(SourceProductionContext contex
)
);
- if (item is RequestItem { Response: { Symbol: ITypeParameterSymbol } } ri)
+ if (request is { Response.Symbol: ITypeParameterSymbol })
{
- method = method.AddTypeParameterListParameters(TypeParameter(ri.Response.Symbol.Name));
+ method = method.AddTypeParameterListParameters(TypeParameter(request.Response.Symbol.Name));
}
if (request.IsUnit)
@@ -65,24 +65,27 @@ public IEnumerable Apply(SourceProductionContext contex
var methodFactory = MakeFactory(
extensionMethodContext.GetRegistryParameterList(),
registrationOptions.Syntax,
- item.Capability?.Syntax
+ request.Capability?.Syntax,
+ request.PartialHasInitialValue
);
var factory = methodFactory(method);
yield return factory(
CreateAsyncFunc(request.Response.Syntax, false, request.Request.Syntax),
- resolve.ReturnIfNotNull(static r => CreateAsyncFunc(r.Response.Syntax, false, r.Request.Syntax))
+ resolve.ReturnIfNotNull(static r => CreateAsyncFunc(r.Response.Syntax, false, r.Request.Syntax)),
+ null
);
yield return factory(
CreateAsyncFunc(request.Response.Syntax, true, request.Request.Syntax),
- resolve.ReturnIfNotNull(static r => CreateAsyncFunc(r.Response.Syntax, true, r.Request.Syntax))
+ resolve.ReturnIfNotNull(static r => CreateAsyncFunc(r.Response.Syntax, true, r.Request.Syntax)),
+ null
);
if (allowDerivedRequests)
{
var genericFactory = MakeGenericFactory(factory, request.Request.Syntax);
- yield return genericFactory(CreateAsyncFunc(request.Response.Syntax, false, IdentifierName("T")), null);
- yield return genericFactory(CreateAsyncFunc(request.Response.Syntax, true, IdentifierName("T")), null);
+ yield return genericFactory(CreateAsyncFunc(request.Response.Syntax, false, IdentifierName("T")), null, null);
+ yield return genericFactory(CreateAsyncFunc(request.Response.Syntax, true, IdentifierName("T")), null, null);
}
{
@@ -90,13 +93,14 @@ public IEnumerable Apply(SourceProductionContext contex
{
yield return factory(
CreateAsyncFunc(request.Response.Syntax, true, request.Request.Syntax, capability.Syntax),
- resolve.ReturnIfNotNull(r => CreateAsyncFunc(r.Response.Syntax, true, r.Request.Syntax, capability.Syntax))
+ resolve.ReturnIfNotNull(r => CreateAsyncFunc(r.Response.Syntax, true, r.Request.Syntax, capability.Syntax)),
+ null
);
if (allowDerivedRequests)
{
var genericFactory = MakeGenericFactory(factory, request.Request.Syntax);
- yield return genericFactory(CreateAsyncFunc(request.Response.Syntax, true, IdentifierName("T"), capability.Syntax), null);
+ yield return genericFactory(CreateAsyncFunc(request.Response.Syntax, true, IdentifierName("T"), capability.Syntax), null, null);
}
}
}
@@ -120,24 +124,29 @@ public IEnumerable Apply(SourceProductionContext contex
yield return factory(
CreatePartialAction(request.Request.Syntax, partialItemsSyntax, false),
- resolve.ReturnIfNotNull(r => CreateAsyncFunc(r.Response.Syntax, false, r.Request.Syntax))
+ resolve.ReturnIfNotNull(r => CreateAsyncFunc(r.Response.Syntax, false, r.Request.Syntax)),
+ CreateAsyncFunc(request.Response.Syntax, false, request.Request.Syntax)
);
yield return factory(
CreatePartialAction(request.Request.Syntax, partialItemsSyntax, true),
- resolve.ReturnIfNotNull(r => CreateAsyncFunc(r.Response.Syntax, true, r.Request.Syntax))
+ resolve.ReturnIfNotNull(r => CreateAsyncFunc(r.Response.Syntax, true, r.Request.Syntax)),
+ CreateAsyncFunc(request.Response.Syntax, true, request.Request.Syntax)
);
if (allowDerivedRequests)
{
var genericFactory = MakeGenericFactory(factory, request.Request.Syntax);
- yield return genericFactory(CreatePartialAction(IdentifierName("T"), partialItemsSyntax, false), null);
- yield return genericFactory(CreatePartialAction(IdentifierName("T"), partialItemsSyntax, true), null);
+ yield return genericFactory(CreatePartialAction(IdentifierName("T"), partialItemsSyntax, false), null,
+ CreateAsyncFunc(request.Response.Syntax, false, request.Request.Syntax));
+ yield return genericFactory(CreatePartialAction(IdentifierName("T"), partialItemsSyntax, true), null,
+ CreateAsyncFunc(request.Response.Syntax, true, request.Request.Syntax));
}
if (request.Capability is { } capability)
{
yield return factory(
CreatePartialAction(request.Request.Syntax, partialItemsSyntax, true, capability.Syntax),
- resolve.ReturnIfNotNull(r => CreateAsyncFunc(r.Response.Syntax, true, r.Request.Syntax, capability.Syntax))
+ resolve.ReturnIfNotNull(r => CreateAsyncFunc(r.Response.Syntax, true, r.Request.Syntax, capability.Syntax)),
+ CreateAsyncFunc(request.Response.Syntax, true, request.Request.Syntax)
);
}
}
@@ -160,47 +169,61 @@ public IEnumerable Apply(SourceProductionContext contex
yield return factory(
CreatePartialAction(request.Request.Syntax, partialItem.Syntax, false),
- resolve.ReturnIfNotNull(r => CreateAsyncFunc(r.Response.Syntax, false, r.Request.Syntax))
+ resolve.ReturnIfNotNull(r => CreateAsyncFunc(r.Response.Syntax, false, r.Request.Syntax)),
+ CreateAsyncFunc(request.Response.Syntax, false, request.Request.Syntax)
);
yield return factory(
CreatePartialAction(request.Request.Syntax, partialItem.Syntax, true),
- resolve.ReturnIfNotNull(r => CreateAsyncFunc(r.Response.Syntax, true, r.Request.Syntax))
+ resolve.ReturnIfNotNull(r => CreateAsyncFunc(r.Response.Syntax, true, r.Request.Syntax)),
+ CreateAsyncFunc(request.Response.Syntax, true, request.Request.Syntax)
);
if (allowDerivedRequests)
{
var genericFactory = MakeGenericFactory(factory, request.Request.Syntax);
- yield return genericFactory(CreatePartialAction(IdentifierName("T"), partialItem.Syntax, false), null);
- yield return genericFactory(CreatePartialAction(IdentifierName("T"), partialItem.Syntax, true), null);
+ yield return genericFactory(CreatePartialAction(IdentifierName("T"), partialItem.Syntax, false), null,
+ CreateAsyncFunc(request.Response.Syntax, false, request.Request.Syntax));
+ yield return genericFactory(CreatePartialAction(IdentifierName("T"), partialItem.Syntax, true), null,
+ CreateAsyncFunc(request.Response.Syntax, true, request.Request.Syntax));
}
if (request.Capability is { } capability)
{
yield return factory(
CreatePartialAction(request.Request.Syntax, partialItem.Syntax, true, capability.Syntax),
- resolve.ReturnIfNotNull(r => CreateAsyncFunc(r.Response.Syntax, true, r.Request.Syntax, capability.Syntax))
+ resolve.ReturnIfNotNull(r => CreateAsyncFunc(r.Response.Syntax, true, r.Request.Syntax, capability.Syntax)),
+ CreateAsyncFunc(request.Response.Syntax, true, request.Request.Syntax)
);
if (allowDerivedRequests)
{
var genericFactory = MakeGenericFactory(factory, request.Request.Syntax);
- yield return genericFactory(CreatePartialAction(IdentifierName("T"), partialItem.Syntax, true, capability.Syntax), null);
+ yield return genericFactory(CreatePartialAction(IdentifierName("T"), partialItem.Syntax, true, capability.Syntax), null,
+ CreateAsyncFunc(request.Response.Syntax, true, request.Request.Syntax));
}
}
}
}
- private static Func> MakeFactory(
- ParameterListSyntax preParameterList, TypeSyntax registrationOptions, TypeSyntax? capabilityName
+ private static Func> MakeFactory(
+ ParameterListSyntax preParameterList, TypeSyntax registrationOptions, TypeSyntax? capabilityName, bool partialHasInitialValue
)
{
- return method => (syntax, resolveSyntax) => GenerateMethod(method, syntax, resolveSyntax);
+ return method => (syntax, resolveSyntax, initialHandlerSyntax) => generateMethod(method, syntax, resolveSyntax, initialHandlerSyntax);
- MethodDeclarationSyntax MethodFactory(MethodDeclarationSyntax method, TypeSyntax syntax, TypeSyntax? resolveSyntax, ParameterSyntax registrationParameter)
+ MethodDeclarationSyntax methodFactory(MethodDeclarationSyntax method, TypeSyntax syntax, TypeSyntax? resolveSyntax, TypeSyntax? initialHandlerSyntax, ParameterSyntax registrationParameter)
{
return method
.WithParameterList(
preParameterList
+ .AddParameters(
+ partialHasInitialValue && initialHandlerSyntax is {}
+ ? new[] {
+ Parameter(Identifier("initialHandler"))
+ .WithType(initialHandlerSyntax)
+ }
+ : Array.Empty()
+ )
.AddParameters(Parameter(Identifier("handler")).WithType(syntax))
.AddParameters(
resolveSyntax is { }
@@ -208,18 +231,18 @@ resolveSyntax is { }
Parameter(Identifier("resolveHandler"))
.WithType(resolveSyntax)
}
- : new ParameterSyntax[] { }
+ : Array.Empty()
)
.AddParameters(registrationParameter)
);
}
- MethodDeclarationSyntax GenerateMethod(MethodDeclarationSyntax method, TypeSyntax syntax, TypeSyntax? resolveSyntax)
+ MethodDeclarationSyntax generateMethod(MethodDeclarationSyntax method, TypeSyntax syntax, TypeSyntax? resolveSyntax, TypeSyntax? initialHandlerSyntax)
{
if (capabilityName is { })
{
- return MethodFactory(
- method, syntax, resolveSyntax,
+ return methodFactory(
+ method, syntax, resolveSyntax, initialHandlerSyntax,
Parameter(Identifier("registrationOptions"))
.WithType(
GenericName(Identifier("RegistrationOptionsDelegate")).WithTypeArgumentList(
@@ -229,8 +252,8 @@ MethodDeclarationSyntax GenerateMethod(MethodDeclarationSyntax method, TypeSynta
);
}
- return MethodFactory(
- method, syntax, resolveSyntax,
+ return methodFactory(
+ method, syntax, resolveSyntax, initialHandlerSyntax,
Parameter(Identifier("registrationOptions"))
.WithType(
GenericName(Identifier("RegistrationOptionsDelegate"))
@@ -272,6 +295,7 @@ private static BlockSyntax GetRequestHandlerExpression(
capabilityName,
false
),
+ null,
capabilityName,
resolve is not null
)
@@ -315,6 +339,7 @@ private static BlockSyntax GetVoidRequestHandlerExpression(
capabilityName,
false
),
+ null,
capabilityName,
resolve is not null
)
@@ -354,7 +379,7 @@ private static BlockSyntax GetPartialResultsHandlerExpression(
),
CreateHandlerArgument(
IdentifierName("LanguageProtocolDelegatingHandlers"),
- "PartialResults",
+ item.PartialHasInitialValue ? "PartialResultsWithInitialValue" : "PartialResults",
args.ToArray()
)
.WithArgumentList(
@@ -368,6 +393,13 @@ private static BlockSyntax GetPartialResultsHandlerExpression(
capabilityName,
true
),
+ item.PartialHasInitialValue ?
+ GetHandlerAdapterArgument(
+ TypeArgumentList(SeparatedList( new [] { item.Request.Syntax, item.Response.Syntax } )),
+ InitialHandlerArgument,
+ capabilityName,
+ false
+ ): null,
capabilityName
)
)
@@ -405,7 +437,7 @@ private static BlockSyntax GetPartialResultHandlerExpression(
Parameter(
Identifier("_")
),
- CreateHandlerArgument(IdentifierName("LanguageProtocolDelegatingHandlers"), "PartialResult", args.ToArray())
+ CreateHandlerArgument(IdentifierName("LanguageProtocolDelegatingHandlers"), item.PartialHasInitialValue ? "PartialResultWithInitialValue" : "PartialResult", args.ToArray())
.WithArgumentList(
GetPartialResultArgumentList(
IdentifierName("registrationOptions"),
@@ -417,6 +449,13 @@ private static BlockSyntax GetPartialResultHandlerExpression(
capabilityName,
true
),
+ item.PartialHasInitialValue ?
+ GetHandlerAdapterArgument(
+ TypeArgumentList(SeparatedList(new [] { item.Request.Syntax, item.Response.Syntax })),
+ InitialHandlerArgument,
+ capabilityName,
+ false
+ ): null,
capabilityName
)
)
@@ -466,6 +505,7 @@ private static void InsertResolveHandler(
capabilityName,
false
),
+ null,
capabilityName,
true
)
@@ -476,11 +516,12 @@ private static void InsertResolveHandler(
}
private static ArgumentListSyntax GetPartialItemsArgumentList(
- TypeSyntax registrationOptionsName, TypeSyntax registrationType, TypeSyntax responseName, ArgumentSyntax handlerArgument, TypeSyntax? capabilityType
+ TypeSyntax registrationOptionsName, TypeSyntax registrationType, TypeSyntax responseName, ArgumentSyntax handlerArgument, ArgumentSyntax? initialArgument, TypeSyntax? capabilityType
) =>
ArgumentList(
SeparatedList(
new[] {
+ initialArgument!,
handlerArgument,
Argument(GetRegistrationOptionsAdapter(registrationOptionsName, registrationType, capabilityType)),
Argument(
@@ -500,16 +541,17 @@ private static ArgumentListSyntax GetPartialItemsArgumentList(
IdentifierName("From")
)
)
- }
+ }.Where(z => z is not null)
)
);
private static ArgumentListSyntax GetPartialResultArgumentList(
- TypeSyntax registrationOptionsName, TypeSyntax registrationType, TypeSyntax responseName, ArgumentSyntax handlerArgument, TypeSyntax? capabilityType
+ TypeSyntax registrationOptionsName, TypeSyntax registrationType, TypeSyntax responseName, ArgumentSyntax handlerArgument, ArgumentSyntax? initialArgument, TypeSyntax? capabilityType
) =>
ArgumentList(
SeparatedList(
new[] {
+ initialArgument!,
handlerArgument,
Argument(GetRegistrationOptionsAdapter(registrationOptionsName, registrationType, capabilityType)),
Argument(
@@ -529,7 +571,7 @@ private static ArgumentListSyntax GetPartialResultArgumentList(
IdentifierName("From")
)
)
- }
+ }.Where(z => z is not null)
)
);
}
diff --git a/src/JsonRpc.Generators/Strategies/OnRequestMethodGeneratorWithoutRegistrationOptionsStrategy.cs b/src/JsonRpc.Generators/Strategies/OnRequestMethodGeneratorWithoutRegistrationOptionsStrategy.cs
index 0bdcdccaa..2bfb25e58 100644
--- a/src/JsonRpc.Generators/Strategies/OnRequestMethodGeneratorWithoutRegistrationOptionsStrategy.cs
+++ b/src/JsonRpc.Generators/Strategies/OnRequestMethodGeneratorWithoutRegistrationOptionsStrategy.cs
@@ -46,16 +46,18 @@ public IEnumerable Apply(SourceProductionContext contex
method = method.AddTypeParameterListParameters(TypeParameter(ri.Response.Symbol.Name));
}
- var methodFactory = MakeFactory(extensionMethodContext.GetRegistryParameterList());
+ var methodFactory = MakeFactory(extensionMethodContext.GetRegistryParameterList(), request.PartialHasInitialValue);
var factory = methodFactory(method);
yield return factory(
CreateAsyncFunc(request.Response.Syntax, false, request.Request.Syntax),
- resolve.ReturnIfNotNull(static r => CreateAsyncFunc(r.Response.Syntax, false, r.Request.Syntax))
+ resolve.ReturnIfNotNull(static r => CreateAsyncFunc(r.Response.Syntax, false, r.Request.Syntax)),
+ null
);
yield return factory(
CreateAsyncFunc(request.Response.Syntax, true, request.Request.Syntax),
- resolve.ReturnIfNotNull(static r => CreateAsyncFunc(r.Response.Syntax, false, r.Request.Syntax))
+ resolve.ReturnIfNotNull(static r => CreateAsyncFunc(r.Response.Syntax, false, r.Request.Syntax)),
+ null
);
if (allowDerivedRequests)
@@ -63,9 +65,11 @@ public IEnumerable Apply(SourceProductionContext contex
var genericFactory = MakeGenericFactory(factory, request.Request.Syntax);
yield return genericFactory(
- CreateAsyncFunc(request.Response.Syntax, false, IdentifierName("T")), null
+ CreateAsyncFunc(request.Response.Syntax, false, IdentifierName("T")), null,
+ null
);
- yield return genericFactory(CreateAsyncFunc(request.Response.Syntax, true, IdentifierName("T")), null);
+ yield return genericFactory(CreateAsyncFunc(request.Response.Syntax, true, IdentifierName("T")), null,
+ null);
}
{
@@ -94,7 +98,8 @@ public IEnumerable Apply(SourceProductionContext contex
yield return factory(
CreateAsyncFunc(request.Response.Syntax, true, request.Request.Syntax, capability.Syntax),
- resolve.ReturnIfNotNull(r => CreateAsyncFunc(r.Response.Syntax, true, r.Request.Syntax, capability.Syntax))
+ resolve.ReturnIfNotNull(r => CreateAsyncFunc(r.Response.Syntax, true, r.Request.Syntax, capability.Syntax)),
+ null
);
if (allowDerivedRequests)
@@ -102,7 +107,8 @@ public IEnumerable Apply(SourceProductionContext contex
var genericFactory = MakeGenericFactory(factory, request.Request.Syntax);
yield return genericFactory(
CreateAsyncFunc(request.Response.Syntax, true, IdentifierName("T"), capability.Syntax),
- resolve.ReturnIfNotNull(r => CreateAsyncFunc(r.Response.Syntax, true, r.Request.Syntax, capability.Syntax))
+ resolve.ReturnIfNotNull(r => CreateAsyncFunc(r.Response.Syntax, true, r.Request.Syntax, capability.Syntax)),
+ null
);
}
}
@@ -117,29 +123,33 @@ public IEnumerable Apply(SourceProductionContext contex
.WithIdentifier(Identifier(item.JsonRpcAttributes.PartialHandlerMethodName))
.WithExpressionBody(
GetPartialResultsHandlerExpression(
- GetJsonRpcMethodName(extensionMethodContext.TypeDeclaration), request.Request.Syntax, partialItems.Syntax, request.Response.Syntax
+ GetJsonRpcMethodName(extensionMethodContext.TypeDeclaration), request.Request.Syntax, partialItems.Syntax, request.Response.Syntax, request.PartialHasInitialValue
)
)
);
yield return factory(
CreatePartialAction(request.Request.Syntax, partialItemsSyntax, false),
- resolve.ReturnIfNotNull(r => CreateAsyncFunc(r.Response.Syntax, false, r.Request.Syntax))
+ resolve.ReturnIfNotNull(r => CreateAsyncFunc(r.Response.Syntax, false, r.Request.Syntax)),
+ CreateAsyncFunc(request.Response.Syntax, false, request.Request.Syntax)
);
yield return factory(
CreatePartialAction(request.Request.Syntax, partialItemsSyntax, true),
- resolve.ReturnIfNotNull(r => CreateAsyncFunc(r.Response.Syntax, true, r.Request.Syntax))
+ resolve.ReturnIfNotNull(r => CreateAsyncFunc(r.Response.Syntax, true, r.Request.Syntax)),
+ CreateAsyncFunc(request.Response.Syntax, true, request.Request.Syntax)
);
if (allowDerivedRequests)
{
var genericFactory = MakeGenericFactory(factory, request.Request.Syntax);
yield return genericFactory(
CreatePartialAction(IdentifierName("T"), partialItemsSyntax, false),
- resolve.ReturnIfNotNull(r => CreateAsyncFunc(r.Response.Syntax, false, r.Request.Syntax))
+ resolve.ReturnIfNotNull(r => CreateAsyncFunc(r.Response.Syntax, false, r.Request.Syntax)),
+ CreateAsyncFunc(request.Response.Syntax, false, request.Request.Syntax)
);
yield return genericFactory(
CreatePartialAction(IdentifierName("T"), partialItemsSyntax, true),
- resolve.ReturnIfNotNull(r => CreateAsyncFunc(r.Response.Syntax, true, r.Request.Syntax))
+ resolve.ReturnIfNotNull(r => CreateAsyncFunc(r.Response.Syntax, true, r.Request.Syntax)),
+ CreateAsyncFunc(request.Response.Syntax, true, request.Request.Syntax)
);
}
@@ -151,13 +161,14 @@ public IEnumerable Apply(SourceProductionContext contex
.WithExpressionBody(
GetPartialResultsCapabilityHandlerExpression(
GetJsonRpcMethodName(extensionMethodContext.TypeDeclaration), request.Request.Syntax, request.Response.Syntax,
- partialItems.Syntax, capability.Syntax
+ partialItems.Syntax, capability.Syntax, request.PartialHasInitialValue
)
)
);
yield return factory(
CreatePartialAction(request.Request.Syntax, partialItemsSyntax, true, capability.Syntax),
- resolve.ReturnIfNotNull(r => CreateAsyncFunc(r.Response.Syntax, true, r.Request.Syntax, capability.Syntax))
+ resolve.ReturnIfNotNull(r => CreateAsyncFunc(r.Response.Syntax, true, r.Request.Syntax, capability.Syntax)),
+ CreateAsyncFunc(request.Response.Syntax, true, request.Request.Syntax)
);
if (allowDerivedRequests)
@@ -165,7 +176,8 @@ public IEnumerable Apply(SourceProductionContext contex
var genericFactory = MakeGenericFactory(factory, request.Request.Syntax);
yield return genericFactory(
CreatePartialAction(IdentifierName("T"), partialItemsSyntax, true, capability.Syntax),
- resolve.ReturnIfNotNull(r => CreateAsyncFunc(r.Response.Syntax, true, r.Request.Syntax, capability.Syntax))
+ resolve.ReturnIfNotNull(r => CreateAsyncFunc(r.Response.Syntax, true, r.Request.Syntax, capability.Syntax)),
+ CreateAsyncFunc(request.Response.Syntax, true, request.Request.Syntax)
);
}
}
@@ -176,24 +188,28 @@ public IEnumerable Apply(SourceProductionContext contex
factory = methodFactory(
method.WithExpressionBody(
GetPartialResultHandlerExpression(
- GetJsonRpcMethodName(extensionMethodContext.TypeDeclaration), request.Request.Syntax, partialItem.Syntax, request.Response.Syntax
+ GetJsonRpcMethodName(extensionMethodContext.TypeDeclaration), request.Request.Syntax, partialItem.Syntax, request.Response.Syntax, request.PartialHasInitialValue
)
)
);
yield return factory(
CreatePartialAction(request.Request.Syntax, partialItem.Syntax, false),
- resolve.ReturnIfNotNull(r => CreateAsyncFunc(r.Response.Syntax, false, r.Request.Syntax))
+ resolve.ReturnIfNotNull(r => CreateAsyncFunc(r.Response.Syntax, false, r.Request.Syntax)),
+ CreateAsyncFunc(request.Response.Syntax, false, request.Request.Syntax)
);
yield return factory(
CreatePartialAction(request.Request.Syntax, partialItem.Syntax, true),
- resolve.ReturnIfNotNull(r => CreateAsyncFunc(r.Response.Syntax, true, r.Request.Syntax))
+ resolve.ReturnIfNotNull(r => CreateAsyncFunc(r.Response.Syntax, true, r.Request.Syntax)),
+ CreateAsyncFunc(request.Response.Syntax, true, request.Request.Syntax)
);
if (allowDerivedRequests)
{
var genericFactory = MakeGenericFactory(factory, request.Request.Syntax);
- yield return genericFactory(CreatePartialAction(IdentifierName("T"), partialItem.Syntax, false), null);
- yield return genericFactory(CreatePartialAction(IdentifierName("T"), partialItem.Syntax, true), null);
+ yield return genericFactory(CreatePartialAction(IdentifierName("T"), partialItem.Syntax, false), null,
+ CreateAsyncFunc(request.Response.Syntax, false, request.Response.Syntax, partialItem.Syntax));
+ yield return genericFactory(CreatePartialAction(IdentifierName("T"), partialItem.Syntax, true), null,
+ CreateAsyncFunc(request.Response.Syntax, true, request.Response.Syntax, partialItem.Syntax));
}
if (request.Capability is { } capability)
@@ -201,35 +217,45 @@ public IEnumerable Apply(SourceProductionContext contex
factory = methodFactory(
method.WithExpressionBody(
GetPartialResultCapabilityHandlerExpression(
- GetJsonRpcMethodName(extensionMethodContext.TypeDeclaration), request.Request.Syntax, partialItem.Syntax, request.Response.Syntax, capability.Syntax
+ GetJsonRpcMethodName(extensionMethodContext.TypeDeclaration), request.Request.Syntax, partialItem.Syntax, request.Response.Syntax, capability.Syntax, request.PartialHasInitialValue
)
)
);
yield return factory(
CreatePartialAction(request.Request.Syntax, partialItem.Syntax, true, capability.Syntax),
- resolve.ReturnIfNotNull(r => CreateAsyncFunc(r.Response.Syntax, true, r.Request.Syntax, capability.Syntax))
+ resolve.ReturnIfNotNull(r => CreateAsyncFunc(r.Response.Syntax, true, r.Request.Syntax, capability.Syntax)),
+ CreateAsyncFunc(request.Response.Syntax, true, request.Request.Syntax)
);
if (allowDerivedRequests)
{
var genericFactory = MakeGenericFactory(factory, request.Request.Syntax);
- yield return genericFactory(CreatePartialAction(IdentifierName("T"), partialItem.Syntax, true, capability.Syntax), null);
+ yield return genericFactory(CreatePartialAction(IdentifierName("T"), partialItem.Syntax, true, capability.Syntax), null,
+ CreateAsyncFunc(request.Response.Syntax, true, request.Request.Syntax));
}
}
}
}
- private static Func> MakeFactory(
- ParameterListSyntax preParameterList
+ private static Func> MakeFactory(
+ ParameterListSyntax preParameterList, bool partialHasInitialValue
)
{
- return method => (syntax, resolveSyntax) => GenerateMethods(method, syntax, resolveSyntax);
+ return method => (syntax, resolveSyntax, initialHandlerSyntax) => generateMethods(method, syntax, resolveSyntax, initialHandlerSyntax);
- MethodDeclarationSyntax MethodFactory(MethodDeclarationSyntax method, TypeSyntax syntax, TypeSyntax? resolveSyntax)
+ MethodDeclarationSyntax methodFactory(MethodDeclarationSyntax method, TypeSyntax syntax, TypeSyntax? resolveSyntax, TypeSyntax? initialHandlerSyntax)
{
return method
.WithParameterList(
preParameterList
+ .AddParameters(
+ partialHasInitialValue && initialHandlerSyntax is {}
+ ? new[] {
+ Parameter(Identifier("initialHandler"))
+ .WithType(initialHandlerSyntax)
+ }
+ : Array.Empty()
+ )
.AddParameters(Parameter(Identifier("handler")).WithType(syntax))
.AddParameters(
resolveSyntax is { }
@@ -237,12 +263,12 @@ resolveSyntax is { }
Parameter(Identifier("resolveHandler"))
.WithType(resolveSyntax)
}
- : new ParameterSyntax[] { }
+ : Array.Empty()
)
);
}
- MethodDeclarationSyntax GenerateMethods(MethodDeclarationSyntax method, TypeSyntax syntax, TypeSyntax? resolveSyntax) => MethodFactory(method, syntax, resolveSyntax);
+ MethodDeclarationSyntax generateMethods(MethodDeclarationSyntax method, TypeSyntax syntax, TypeSyntax? resolveSyntax, TypeSyntax? initialHandlerSyntax) => methodFactory(method, syntax, resolveSyntax, initialHandlerSyntax);
}
}
}
diff --git a/src/JsonRpc.Generators/Strategies/OnRequestTypedResolveMethodGeneratorWithRegistrationOptionsStrategy.cs b/src/JsonRpc.Generators/Strategies/OnRequestTypedResolveMethodGeneratorWithRegistrationOptionsStrategy.cs
index 303f9908d..09773d9e7 100644
--- a/src/JsonRpc.Generators/Strategies/OnRequestTypedResolveMethodGeneratorWithRegistrationOptionsStrategy.cs
+++ b/src/JsonRpc.Generators/Strategies/OnRequestTypedResolveMethodGeneratorWithRegistrationOptionsStrategy.cs
@@ -42,6 +42,7 @@ public IEnumerable Apply(SourceProductionContext contex
responseType = GenericName(Identifier("CodeActionContainer"))
.WithTypeArgumentList(TypeArgumentList(SingletonSeparatedList(IdentifierName("T"))));
}
+
responseType = request.Response.Syntax is NullableTypeSyntax ? NullableType(responseType) : responseType;
var method = MethodDeclaration(extensionMethodContext.Item, item.JsonRpcAttributes.HandlerMethodName)
@@ -66,17 +67,20 @@ public IEnumerable Apply(SourceProductionContext contex
var methodFactory = MakeFactory(
extensionMethodContext.GetRegistryParameterList(),
registrationOptions.Syntax,
- item.Capability?.Syntax
+ item.Capability?.Syntax,
+ request.PartialHasInitialValue
);
var factory = methodFactory(method);
yield return factory(
CreateAsyncFunc(responseType, false, requestType),
- CreateAsyncFunc(resolveType, false, resolveType)
+ CreateAsyncFunc(resolveType, false, resolveType),
+ null
);
yield return factory(
CreateAsyncFunc(responseType, true, requestType),
- CreateAsyncFunc(resolveType, true, resolveType)
+ CreateAsyncFunc(resolveType, true, resolveType),
+ null
);
{
@@ -84,7 +88,8 @@ public IEnumerable Apply(SourceProductionContext contex
{
yield return factory(
CreateAsyncFunc(responseType, true, requestType, capability.Syntax),
- CreateAsyncFunc(resolveType, true, resolveType, capability.Syntax)
+ CreateAsyncFunc(resolveType, true, resolveType, capability.Syntax),
+ null
);
}
}
@@ -101,6 +106,7 @@ public IEnumerable Apply(SourceProductionContext contex
request,
requestType,
resolveType,
+ responseType,
registrationOptions.Syntax,
item.Capability?.Syntax
)
@@ -109,18 +115,21 @@ public IEnumerable Apply(SourceProductionContext contex
yield return factory(
CreatePartialAction(requestType, enumerableType, false),
- CreateAsyncFunc(resolveType, false, resolveType)
+ CreateAsyncFunc(resolveType, false, resolveType),
+ CreateAsyncFunc(responseType, false, requestType)
);
yield return factory(
CreatePartialAction(requestType, enumerableType, true),
- CreateAsyncFunc(resolveType, true, resolveType)
+ CreateAsyncFunc(resolveType, true, resolveType),
+ CreateAsyncFunc(responseType, true, requestType)
);
if (request.Capability is { } capability)
{
yield return factory(
CreatePartialAction(requestType, enumerableType, true, capability.Syntax),
- CreateAsyncFunc(resolveType, true, resolveType, capability.Syntax)
+ CreateAsyncFunc(resolveType, true, resolveType, capability.Syntax),
+ CreateAsyncFunc(responseType, true, requestType)
);
}
}
@@ -135,6 +144,7 @@ public IEnumerable Apply(SourceProductionContext contex
request,
requestType,
resolveType,
+ responseType,
registrationOptions.Syntax,
item.Capability?.Syntax
)
@@ -143,53 +153,67 @@ public IEnumerable Apply(SourceProductionContext contex
yield return factory(
CreatePartialAction(requestType, resolveType, false),
- CreateAsyncFunc(resolveType, false, resolveType)
+ CreateAsyncFunc(resolveType, false, resolveType),
+ CreateAsyncFunc(responseType, false, requestType)
);
yield return factory(
CreatePartialAction(requestType, resolveType, true),
- CreateAsyncFunc(resolveType, true, resolveType)
+ CreateAsyncFunc(resolveType, true, resolveType),
+ CreateAsyncFunc(responseType, true, requestType)
);
if (request.Capability is { } capability)
{
yield return factory(
CreatePartialAction(requestType, resolveType, true, capability.Syntax),
- CreateAsyncFunc(resolveType, true, resolveType, capability.Syntax)
+ CreateAsyncFunc(resolveType, true, resolveType, capability.Syntax),
+ CreateAsyncFunc(responseType, true, requestType)
);
}
}
}
- private static Func> MakeFactory(
- ParameterListSyntax preParameterList, TypeSyntax registrationOptions, TypeSyntax? capabilityName
+ private static Func> MakeFactory(
+ ParameterListSyntax preParameterList, TypeSyntax registrationOptions, TypeSyntax? capabilityName, bool partialHasInitialValue
)
{
- return method => (syntax, resolveSyntax) => GenerateMethod(method, syntax, resolveSyntax);
+ return method => (syntax, resolveSyntax, initialValueSyntax) => GenerateMethod(method, syntax, resolveSyntax, initialValueSyntax);
- MethodDeclarationSyntax MethodFactory(MethodDeclarationSyntax method, TypeSyntax syntax, TypeSyntax? resolveSyntax, ParameterSyntax registrationParameter)
+ MethodDeclarationSyntax MethodFactory(
+ MethodDeclarationSyntax method, TypeSyntax syntax, TypeSyntax? resolveSyntax, TypeSyntax? initialHandlerSyntax, ParameterSyntax registrationParameter
+ )
{
return method
- .WithParameterList(
- preParameterList
- .AddParameters(Parameter(Identifier("handler")).WithType(syntax))
- .AddParameters(
- resolveSyntax is { }
- ? new[] {
- Parameter(Identifier("resolveHandler"))
- .WithType(resolveSyntax)
- }
- : new ParameterSyntax[] { }
- )
- .AddParameters(registrationParameter)
- );
+ .WithParameterList(
+ preParameterList
+ .AddParameters(
+ partialHasInitialValue && initialHandlerSyntax is {}
+ ? new[] {
+ Parameter(Identifier("initialHandler"))
+ .WithType(initialHandlerSyntax)
+ }
+ : Array.Empty()
+ )
+ .AddParameters(Parameter(Identifier("handler")).WithType(syntax))
+ .AddParameters(
+ resolveSyntax is { }
+ ? new[]
+ {
+ Parameter(Identifier("resolveHandler"))
+ .WithType(resolveSyntax)
+ }
+ : new ParameterSyntax[] { }
+ )
+ .AddParameters(registrationParameter)
+ );
}
- MethodDeclarationSyntax GenerateMethod(MethodDeclarationSyntax method, TypeSyntax syntax, TypeSyntax? resolveSyntax)
+ MethodDeclarationSyntax GenerateMethod(MethodDeclarationSyntax method, TypeSyntax syntax, TypeSyntax? resolveSyntax, TypeSyntax? initialHandlerSyntax)
{
if (capabilityName is { })
{
return MethodFactory(
- method, syntax, resolveSyntax,
+ method, syntax, resolveSyntax, initialHandlerSyntax,
Parameter(Identifier("registrationOptions"))
.WithType(
GenericName(Identifier("RegistrationOptionsDelegate")).WithTypeArgumentList(
@@ -200,7 +224,7 @@ MethodDeclarationSyntax GenerateMethod(MethodDeclarationSyntax method, TypeSynta
}
return MethodFactory(
- method, syntax, resolveSyntax,
+ method, syntax, resolveSyntax, initialHandlerSyntax,
Parameter(Identifier("registrationOptions"))
.WithType(
GenericName(Identifier("RegistrationOptionsDelegate"))
@@ -229,29 +253,32 @@ private static BlockSyntax GetRequestHandlerExpression(
typeArgs = typeArgs.Add(capabilityName);
}
- return Block(ReturnStatement(
- AddHandler(
- Argument(
- CreateHandlerArgument($"Delegating{request.JsonRpcAttributes.HandlerName}Handler", IdentifierName("T"))
- .WithArgumentList(
- HandlerArgumentList(
- IdentifierName("registrationOptions"),
- registrationOptions,
- capabilityName,
- TypeArgumentList(SeparatedList(handlerAdapterArgs)),
- TypeArgumentList(SeparatedList(resolveAdapterArgs)),
- TypeArgumentList(SeparatedList(typeArgs.ToArray()))
- )
- )
- )
- )
- ));
+ return Block(
+ ReturnStatement(
+ AddHandler(
+ Argument(
+ CreateHandlerArgument($"Delegating{request.JsonRpcAttributes.HandlerName}Handler", IdentifierName("T"))
+ .WithArgumentList(
+ HandlerArgumentList(
+ IdentifierName("registrationOptions"),
+ registrationOptions,
+ capabilityName,
+ TypeArgumentList(SeparatedList(handlerAdapterArgs)),
+ TypeArgumentList(SeparatedList(resolveAdapterArgs)),
+ TypeArgumentList(SeparatedList(typeArgs.ToArray()))
+ )
+ )
+ )
+ )
+ )
+ );
}
private static BlockSyntax GetPartialHandlerExpression(
RequestItem request,
TypeSyntax requestSyntax,
TypeSyntax resolveSyntax,
+ TypeSyntax responseSyntax,
TypeSyntax registrationOptions,
TypeSyntax? capabilityName
)
@@ -259,33 +286,46 @@ private static BlockSyntax GetPartialHandlerExpression(
var typeArgs = ImmutableArray.Create(registrationOptions);
var handlerAdapterArgs = ImmutableArray.Create(requestSyntax, resolveSyntax);
var resolveAdapterArgs = ImmutableArray.Create(resolveSyntax, resolveSyntax);
+ var initialValueAdapterArgs = ImmutableArray.Create(requestSyntax, responseSyntax);
if (capabilityName is { })
{
typeArgs = typeArgs.Add(capabilityName);
}
- return Block(ReturnStatement(
- AddHandler(
- Argument(
- SimpleLambdaExpression(
- Parameter(
- Identifier("_")
- ),
- CreateHandlerArgument($"Delegating{request.JsonRpcAttributes.HandlerName}PartialHandler", IdentifierName("T"))
- .WithArgumentList(
- PartialHandlerArgumentList(
- IdentifierName("registrationOptions"),
- registrationOptions,
- capabilityName,
- TypeArgumentList(SeparatedList(handlerAdapterArgs)),
- TypeArgumentList(SeparatedList(resolveAdapterArgs)),
- TypeArgumentList(SeparatedList(typeArgs.ToArray()))
- )
- )
+ return Block(
+ ReturnStatement(
+ AddHandler(
+ Argument(
+ SimpleLambdaExpression(
+ Parameter(Identifier("_")),
+ CreateHandlerArgument($"Delegating{request.JsonRpcAttributes.HandlerName}PartialHandler", IdentifierName("T"))
+ .WithArgumentList(
+ PartialHandlerArgumentList(
+ IdentifierName("registrationOptions"),
+ registrationOptions,
+ capabilityName,
+ TypeArgumentList(SeparatedList(handlerAdapterArgs)),
+ TypeArgumentList(SeparatedList(resolveAdapterArgs)),
+ TypeArgumentList(SeparatedList(typeArgs.ToArray()))
+ ).AddArguments(
+ request.PartialHasInitialValue
+ ? new[]
+ {
+ GetHandlerAdapterArgument(
+ TypeArgumentList(SeparatedList(initialValueAdapterArgs)),
+ InitialHandlerArgument,
+ capabilityName,
+ false
+ )
+ }
+ : Array.Empty()
+ )
)
- )
- )
- ));
+ )
+ )
+ )
+ )
+ );
}
public static ArgumentListSyntax HandlerArgumentList(
@@ -298,7 +338,8 @@ TypeArgumentListSyntax registrationAdapterArgs
) =>
ArgumentList(
SeparatedList(
- new[] {
+ new[]
+ {
Argument(GetRegistrationOptionsAdapter(registrationOptionsName, registrationType, capabilityName)),
GetHandlerAdapterArgument(
handlerAdapterArgs,
@@ -326,7 +367,8 @@ TypeArgumentListSyntax registrationAdapterArgs
) =>
ArgumentList(
SeparatedList(
- new[] {
+ new[]
+ {
Argument(
InvocationExpression(
MemberAccessExpression(
diff --git a/src/JsonRpc.Generators/Strategies/OnRequestTypedResolveMethodGeneratorWithoutRegistrationOptionsStrategy.cs b/src/JsonRpc.Generators/Strategies/OnRequestTypedResolveMethodGeneratorWithoutRegistrationOptionsStrategy.cs
index a7f88defc..9b6a83b3f 100644
--- a/src/JsonRpc.Generators/Strategies/OnRequestTypedResolveMethodGeneratorWithoutRegistrationOptionsStrategy.cs
+++ b/src/JsonRpc.Generators/Strategies/OnRequestTypedResolveMethodGeneratorWithoutRegistrationOptionsStrategy.cs
@@ -118,7 +118,7 @@ public IEnumerable Apply(SourceProductionContext contex
.WithIdentifier(Identifier(item.JsonRpcAttributes.PartialHandlerMethodName))
.WithExpressionBody(
GetPartialResultsHandlerExpression(
- GetJsonRpcMethodName(extensionMethodContext.TypeDeclaration), requestType, partialItems.Syntax, responseType
+ GetJsonRpcMethodName(extensionMethodContext.TypeDeclaration), requestType, partialItems.Syntax, responseType, request.PartialHasInitialValue
)
)
);
@@ -140,7 +140,7 @@ public IEnumerable Apply(SourceProductionContext contex
.WithExpressionBody(
GetPartialResultsCapabilityHandlerExpression(
GetJsonRpcMethodName(extensionMethodContext.TypeDeclaration), requestType, responseType,
- resolveType, capability.Syntax
+ resolveType, capability.Syntax, request.PartialHasInitialValue
)
)
);
@@ -157,7 +157,7 @@ public IEnumerable Apply(SourceProductionContext contex
factory = methodFactory(
method.WithExpressionBody(
GetPartialResultHandlerExpression(
- GetJsonRpcMethodName(extensionMethodContext.TypeDeclaration), requestType, observerType, responseType
+ GetJsonRpcMethodName(extensionMethodContext.TypeDeclaration), requestType, observerType, responseType, request.PartialHasInitialValue
)
)
);
@@ -175,7 +175,7 @@ public IEnumerable Apply(SourceProductionContext contex
factory = methodFactory(
method.WithExpressionBody(
GetPartialResultCapabilityHandlerExpression(
- GetJsonRpcMethodName(extensionMethodContext.TypeDeclaration), requestType, observerType, responseType, capability.Syntax
+ GetJsonRpcMethodName(extensionMethodContext.TypeDeclaration), requestType, observerType, responseType, capability.Syntax, request.PartialHasInitialValue
)
)
);
diff --git a/src/JsonRpc.Generators/Strategies/SendMethodNotificationStrategy.cs b/src/JsonRpc.Generators/Strategies/SendMethodNotificationStrategy.cs
index 265473f86..9ae36ef86 100644
--- a/src/JsonRpc.Generators/Strategies/SendMethodNotificationStrategy.cs
+++ b/src/JsonRpc.Generators/Strategies/SendMethodNotificationStrategy.cs
@@ -25,19 +25,19 @@ public IEnumerable Apply(SourceProductionContext contex
.WithSemicolonToken(Token(SyntaxKind.SemicolonToken));
yield return method
- .WithParameterList(
- ParameterList(
- SeparatedList(
- new[] {
- Parameter(Identifier("mediator"))
- .WithType(extensionMethodContext.Item)
- .WithModifiers(TokenList(Token(SyntaxKind.ThisKeyword))),
- Parameter(Identifier("request"))
- .WithType(notification.Request.Syntax)
- }
- )
- )
- );
+ .WithParameterList(
+ ParameterList(
+ SeparatedList(
+ new[] {
+ Parameter(Identifier("mediator"))
+ .WithType(extensionMethodContext.Item)
+ .WithModifiers(TokenList(Token(SyntaxKind.ThisKeyword))),
+ Parameter(Identifier("request"))
+ .WithType(notification.Request.Syntax)
+ }
+ )
+ )
+ );
}
}
}
diff --git a/src/JsonRpc.Generators/Strategies/SendMethodRequestStrategy.cs b/src/JsonRpc.Generators/Strategies/SendMethodRequestStrategy.cs
index 7bbc19ce3..b7d2f28a4 100644
--- a/src/JsonRpc.Generators/Strategies/SendMethodRequestStrategy.cs
+++ b/src/JsonRpc.Generators/Strategies/SendMethodRequestStrategy.cs
@@ -16,7 +16,8 @@ public IEnumerable Apply(SourceProductionContext contex
var parameterList = ParameterList(
SeparatedList(
- new[] {
+ new[]
+ {
Parameter(Identifier("mediator"))
.WithType(extensionMethodContext.Item)
.WithModifiers(TokenList(Token(SyntaxKind.ThisKeyword))),
@@ -43,7 +44,8 @@ public IEnumerable Apply(SourceProductionContext contex
.WithTypeArgumentList(
TypeArgumentList(
SeparatedList(
- new[] {
+ new[]
+ {
request.PartialItem.Syntax,
request.Response!.Syntax
}
@@ -59,7 +61,13 @@ public IEnumerable Apply(SourceProductionContext contex
)
)
.WithParameterList(parameterList)
- .WithExpressionBody(Helpers.GetPartialInvokeExpression(request.Response.Syntax, request.PartialItem.Syntax))
+ .WithExpressionBody(
+ Helpers.GetPartialInvokeExpression(
+ request.Response.Syntax,
+ request.PartialHasInitialValue ? null : request.PartialItem.Syntax,
+ request.PartialItemInheritsFromSelf
+ )
+ )
.WithSemicolonToken(Token(SyntaxKind.SemicolonToken));
yield break;
}
@@ -67,7 +75,8 @@ public IEnumerable Apply(SourceProductionContext contex
if (request.PartialItems is not null)
{
request.AdditionalUsings.Add("OmniSharp.Extensions.LanguageServer.Protocol.Progress");
- var partialItemsSyntax = GenericName("IEnumerable").WithTypeArgumentList(TypeArgumentList(SeparatedList(new[] { request.PartialItems!.Syntax })));
+ var partialItemsSyntax =
+ GenericName("IEnumerable").WithTypeArgumentList(TypeArgumentList(SeparatedList(new[] { request.PartialItems!.Syntax })));
yield return MethodDeclaration(
GenericName(
Identifier("IRequestProgressObservable")
@@ -75,7 +84,8 @@ public IEnumerable Apply(SourceProductionContext contex
.WithTypeArgumentList(
TypeArgumentList(
SeparatedList(
- new[] {
+ new[]
+ {
partialItemsSyntax,
request.Response!.Syntax
}
@@ -91,7 +101,7 @@ public IEnumerable Apply(SourceProductionContext contex
)
)
.WithParameterList(parameterList)
- .WithExpressionBody(Helpers.GetPartialInvokeExpression(request.Response.Syntax, default))
+ .WithExpressionBody(Helpers.GetPartialInvokeExpression(request.Response.Syntax, default, false))
.WithSemicolonToken(Token(SyntaxKind.SemicolonToken));
yield break;
}
@@ -115,6 +125,7 @@ public IEnumerable Apply(SourceProductionContext contex
.WithParameterList(parameterList)
.WithExpressionBody(Helpers.GetRequestInvokeExpression())
.WithSemicolonToken(Token(SyntaxKind.SemicolonToken));
+
}
}
}
diff --git a/src/JsonRpc.Generators/Strategies/SendMethodTypedResolveRequestStrategy.cs b/src/JsonRpc.Generators/Strategies/SendMethodTypedResolveRequestStrategy.cs
new file mode 100644
index 000000000..e0191d84b
--- /dev/null
+++ b/src/JsonRpc.Generators/Strategies/SendMethodTypedResolveRequestStrategy.cs
@@ -0,0 +1,133 @@
+using System.Net;
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CSharp;
+using Microsoft.CodeAnalysis.CSharp.Syntax;
+using OmniSharp.Extensions.JsonRpc.Generators.Contexts;
+using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
+
+namespace OmniSharp.Extensions.JsonRpc.Generators.Strategies;
+
+internal class SendMethodTypedResolveRequestStrategy : IExtensionMethodContextGeneratorStrategy
+{
+ public IEnumerable Apply(SourceProductionContext context, ExtensionMethodContext extensionMethodContext, GeneratorData item)
+ {
+ if (item is not RequestItem request) yield break;
+ if (extensionMethodContext is not { IsProxy: true }) yield break;
+ if (item.JsonRpcAttributes.AllowDerivedRequests) yield break;
+ if (item is not { LspAttributes: { Resolver: { } } }) yield break;
+ if (request.Response.Syntax.GetSyntaxName() == "Unit") yield break;
+// if (request.Request.Symbol.Name != "OutlayHintParams") yield break;
+
+ TypeSyntax requestType = item.Request.Syntax;
+ TypeSyntax responseType = GenericName(Identifier(request.Response.Symbol.Name))
+ .WithTypeArgumentList(TypeArgumentList(SingletonSeparatedList(IdentifierName("T"))));
+
+ responseType = request.Response.Syntax is NullableTypeSyntax ? NullableType(responseType) : responseType;
+
+ var parameterList = ParameterList(
+ SeparatedList(
+ new[]
+ {
+ Parameter(Identifier("mediator"))
+ .WithType(extensionMethodContext.Item)
+ .WithModifiers(TokenList(Token(SyntaxKind.ThisKeyword))),
+ Parameter(Identifier("request"))
+ .WithType(requestType),
+ Parameter(Identifier("cancellationToken"))
+ .WithType(IdentifierName("CancellationToken"))
+ .WithDefault(
+ EqualsValueClause(
+ LiteralExpression(SyntaxKind.DefaultLiteralExpression, Token(SyntaxKind.DefaultKeyword))
+ )
+ )
+ }
+ )
+ );
+//
+// if (request.PartialItem is not null)
+// {
+// request.AdditionalUsings.Add("OmniSharp.Extensions.LanguageServer.Protocol.Progress");
+// yield return MethodDeclaration(
+// GenericName(
+// Identifier("IRequestProgressObservable")
+// )
+// .WithTypeArgumentList(
+// TypeArgumentList(
+// SeparatedList(
+// new[]
+// {
+// request.PartialItem.Syntax,
+// responseType
+// }
+// )
+// )
+// ),
+// Identifier(item.JsonRpcAttributes.RequestMethodName)
+// )
+// .WithModifiers(
+// TokenList(
+// Token(SyntaxKind.PublicKeyword),
+// Token(SyntaxKind.StaticKeyword)
+// )
+// )
+// .WithParameterList(parameterList)
+// .WithExpressionBody(
+// Helpers.GetPartialInvokeExpression(
+// request.Response.Syntax,
+// request.PartialHasInitialValue ? null : request.PartialItem.Syntax,
+// request.PartialItemInheritsFromSelf
+// )
+// )
+// .WithSemicolonToken(Token(SyntaxKind.SemicolonToken));
+// yield break;
+// }
+//
+// if (request.PartialItems is not null)
+// {
+// request.AdditionalUsings.Add("OmniSharp.Extensions.LanguageServer.Protocol.Progress");
+// var partialItemsSyntax =
+// GenericName("IEnumerable").WithTypeArgumentList(TypeArgumentList(SeparatedList(new[] { request.PartialItems!.Syntax })));
+// yield return MethodDeclaration(
+// GenericName(
+// Identifier("IRequestProgressObservable")
+// )
+// .WithTypeArgumentList(
+// TypeArgumentList(
+// SeparatedList(
+// new[]
+// {
+// partialItemsSyntax,
+// responseType
+// }
+// )
+// )
+// ),
+// Identifier(item.JsonRpcAttributes.RequestMethodName)
+// )
+// .WithModifiers(
+// TokenList(
+// Token(SyntaxKind.PublicKeyword),
+// Token(SyntaxKind.StaticKeyword)
+// )
+// )
+// .WithParameterList(parameterList)
+// .WithExpressionBody(Helpers.GetPartialInvokeExpression(responseType, default, false))
+// .WithSemicolonToken(Token(SyntaxKind.SemicolonToken));
+// yield break;
+// }
+
+
+ var responseSyntax = GenericName("Task").WithTypeArgumentList(TypeArgumentList(SeparatedList(new[] { responseType })));
+ yield return MethodDeclaration(responseSyntax, item.JsonRpcAttributes.RequestMethodName)
+ .WithModifiers(
+ TokenList(
+ Token(SyntaxKind.PublicKeyword),
+ Token(SyntaxKind.StaticKeyword)
+ )
+ )
+ .WithTypeParameterList(TypeParameterList(SingletonSeparatedList(TypeParameter("T"))))
+ .WithParameterList(parameterList)
+ .WithExpressionBody(Helpers.GetRequestReturningInvokeExpression(Helpers.GetJsonRpcMethodName(item.TypeDeclaration), responseType))
+ .WithSemicolonToken(Token(SyntaxKind.SemicolonToken));
+ }
+}
diff --git a/src/JsonRpc.Generators/Strategies/TypedDelegatingHandlerStrategy.cs b/src/JsonRpc.Generators/Strategies/TypedDelegatingHandlerStrategy.cs
index 21d7b9905..cca004233 100644
--- a/src/JsonRpc.Generators/Strategies/TypedDelegatingHandlerStrategy.cs
+++ b/src/JsonRpc.Generators/Strategies/TypedDelegatingHandlerStrategy.cs
@@ -71,7 +71,8 @@ private TypeDeclarationSyntax CreateDelegatingHandler(RequestItem item, RequestI
.WithTypeArgumentList(
TypeArgumentList(
SeparatedList(
- new[] {
+ new[]
+ {
item.RegistrationOptions.Syntax,
item.Capability.Syntax
}
@@ -80,14 +81,17 @@ private TypeDeclarationSyntax CreateDelegatingHandler(RequestItem item, RequestI
);
handler = handler.AddMembers(
- FieldDeclaration(VariableDeclaration(type).WithVariables(SingletonSeparatedList(VariableDeclarator(Identifier("_registrationOptionsFactory")))))
+ FieldDeclaration(
+ VariableDeclaration(type).WithVariables(SingletonSeparatedList(VariableDeclarator(Identifier("_registrationOptionsFactory"))))
+ )
.WithModifiers(TokenList(Token(SyntaxKind.PrivateKeyword), Token(SyntaxKind.ReadOnlyKeyword))),
MethodDeclaration(item.RegistrationOptions.Syntax, Identifier("CreateRegistrationOptions"))
.WithModifiers(TokenList(Token(SyntaxKind.ProtectedKeyword), Token(SyntaxKind.InternalKeyword), Token(SyntaxKind.OverrideKeyword)))
.WithParameterList(
ParameterList(
SeparatedList(
- new[] {
+ new[]
+ {
Parameter(Identifier("capability")).WithType(item.Capability.Syntax),
Parameter(Identifier("clientCapabilities")).WithType(IdentifierName("ClientCapabilities"))
}
@@ -100,7 +104,8 @@ private TypeDeclarationSyntax CreateDelegatingHandler(RequestItem item, RequestI
.WithArgumentList(
ArgumentList(
SeparatedList(
- new[] {
+ new[]
+ {
Argument(IdentifierName("capability")),
Argument(IdentifierName("clientCapabilities"))
}
@@ -119,7 +124,9 @@ private TypeDeclarationSyntax CreateDelegatingHandler(RequestItem item, RequestI
.WithTypeArgumentList(TypeArgumentList(SingletonSeparatedList(item.RegistrationOptions.Syntax)));
handler = handler.AddMembers(
- FieldDeclaration(VariableDeclaration(type).WithVariables(SingletonSeparatedList(VariableDeclarator(Identifier("_registrationOptionsFactory")))))
+ FieldDeclaration(
+ VariableDeclaration(type).WithVariables(SingletonSeparatedList(VariableDeclarator(Identifier("_registrationOptionsFactory"))))
+ )
.WithModifiers(TokenList(Token(SyntaxKind.PrivateKeyword), Token(SyntaxKind.ReadOnlyKeyword))),
MethodDeclaration(item.RegistrationOptions.Syntax, Identifier("CreateRegistrationOptions"))
.WithModifiers(TokenList(Token(SyntaxKind.ProtectedKeyword), Token(SyntaxKind.InternalKeyword), Token(SyntaxKind.OverrideKeyword)))
@@ -129,7 +136,8 @@ private TypeDeclarationSyntax CreateDelegatingHandler(RequestItem item, RequestI
.WithArgumentList(
ArgumentList(
SeparatedList(
- new[] {
+ new[]
+ {
Argument(IdentifierName("capability")),
Argument(IdentifierName("clientCapabilities"))
}
@@ -239,7 +247,8 @@ private TypeDeclarationSyntax CreateDelegatingHandler(RequestItem item, RequestI
.WithParameterList(
ParameterList(
SeparatedList(
- new[] {
+ new[]
+ {
Parameter(Identifier("request")).WithType(requestType),
Parameter(Identifier("cancellationToken")).WithType(IdentifierName("CancellationToken"))
}
@@ -253,12 +262,14 @@ private TypeDeclarationSyntax CreateDelegatingHandler(RequestItem item, RequestI
ArgumentList(
SeparatedList(
item.Capability is { }
- ? new[] {
+ ? new[]
+ {
Argument(IdentifierName("request")),
Argument(IdentifierName("Capability")),
Argument(IdentifierName("cancellationToken"))
}
- : new[] {
+ : new[]
+ {
Argument(IdentifierName("request")),
Argument(IdentifierName("cancellationToken"))
}
@@ -280,7 +291,8 @@ item.Capability is { }
.WithParameterList(
ParameterList(
SeparatedList(
- new[] {
+ new[]
+ {
Parameter(Identifier("request")).WithType(resolveType),
Parameter(Identifier("cancellationToken")).WithType(IdentifierName("CancellationToken"))
}
@@ -294,12 +306,14 @@ item.Capability is { }
ArgumentList(
SeparatedList(
item.Capability is { }
- ? new[] {
+ ? new[]
+ {
Argument(IdentifierName("request")),
Argument(IdentifierName("Capability")),
Argument(IdentifierName("cancellationToken"))
}
- : new[] {
+ : new[]
+ {
Argument(IdentifierName("request")),
Argument(IdentifierName("cancellationToken"))
}
@@ -378,7 +392,8 @@ private TypeDeclarationSyntax CreateDelegatingPartialHandler(RequestItem item, R
)
);
- var constructorParams = ParameterList(SingletonSeparatedList(Parameter(Identifier("progressManager")).WithType(IdentifierName("IProgressManager"))));
+ var constructorParams =
+ ParameterList(SingletonSeparatedList(Parameter(Identifier("progressManager")).WithType(IdentifierName("IProgressManager"))));
if (item.RegistrationOptions is { })
{
@@ -388,7 +403,8 @@ private TypeDeclarationSyntax CreateDelegatingPartialHandler(RequestItem item, R
.WithTypeArgumentList(
TypeArgumentList(
SeparatedList(
- new[] {
+ new[]
+ {
item.RegistrationOptions.Syntax,
item.Capability.Syntax
}
@@ -397,14 +413,17 @@ private TypeDeclarationSyntax CreateDelegatingPartialHandler(RequestItem item, R
);
handler = handler.AddMembers(
- FieldDeclaration(VariableDeclaration(type).WithVariables(SingletonSeparatedList(VariableDeclarator(Identifier("_registrationOptionsFactory")))))
+ FieldDeclaration(
+ VariableDeclaration(type).WithVariables(SingletonSeparatedList(VariableDeclarator(Identifier("_registrationOptionsFactory"))))
+ )
.WithModifiers(TokenList(Token(SyntaxKind.PrivateKeyword), Token(SyntaxKind.ReadOnlyKeyword))),
MethodDeclaration(item.RegistrationOptions.Syntax, Identifier("CreateRegistrationOptions"))
.WithModifiers(TokenList(Token(SyntaxKind.ProtectedKeyword), Token(SyntaxKind.InternalKeyword), Token(SyntaxKind.OverrideKeyword)))
.WithParameterList(
ParameterList(
SeparatedList(
- new[] {
+ new[]
+ {
Parameter(Identifier("capability")).WithType(item.Capability.Syntax),
Parameter(Identifier("clientCapabilities")).WithType(IdentifierName("ClientCapabilities"))
}
@@ -418,7 +437,8 @@ private TypeDeclarationSyntax CreateDelegatingPartialHandler(RequestItem item, R
ArgumentList(
SeparatedList(
SeparatedList(
- new[] {
+ new[]
+ {
Argument(IdentifierName("capability")),
Argument(IdentifierName("clientCapabilities"))
}
@@ -438,7 +458,9 @@ private TypeDeclarationSyntax CreateDelegatingPartialHandler(RequestItem item, R
.WithTypeArgumentList(TypeArgumentList(SingletonSeparatedList(item.RegistrationOptions.Syntax)));
handler = handler.AddMembers(
- FieldDeclaration(VariableDeclaration(type).WithVariables(SingletonSeparatedList(VariableDeclarator(Identifier("_registrationOptionsFactory")))))
+ FieldDeclaration(
+ VariableDeclaration(type).WithVariables(SingletonSeparatedList(VariableDeclarator(Identifier("_registrationOptionsFactory"))))
+ )
.WithModifiers(TokenList(Token(SyntaxKind.PrivateKeyword), Token(SyntaxKind.ReadOnlyKeyword))),
MethodDeclaration(item.RegistrationOptions.Syntax, Identifier("CreateRegistrationOptions"))
.WithModifiers(TokenList(Token(SyntaxKind.ProtectedKeyword), Token(SyntaxKind.InternalKeyword), Token(SyntaxKind.OverrideKeyword)))
@@ -448,7 +470,8 @@ private TypeDeclarationSyntax CreateDelegatingPartialHandler(RequestItem item, R
.WithArgumentList(
ArgumentList(
SeparatedList(
- new[] {
+ new[]
+ {
Argument(IdentifierName("capability")),
Argument(IdentifierName("clientCapabilities"))
}
@@ -490,6 +513,20 @@ private TypeDeclarationSyntax CreateDelegatingPartialHandler(RequestItem item, R
Parameter(Identifier("handleResolve"))
.WithType(DelegateHelpers.CreateAsyncFunc(resolveType, true, resolveType, item.Capability.Syntax))
);
+ if (item is { PartialHasInitialValue: true })
+ {
+ handler = handler.AddMembers(
+ FieldDeclaration(
+ VariableDeclaration(DelegateHelpers.CreateAsyncFunc(responseType, true, requestType, item.Capability.Syntax))
+ .WithVariables(SingletonSeparatedList(VariableDeclarator(Identifier("_handleInitialValue"))))
+ )
+ .WithModifiers(TokenList(Token(SyntaxKind.PrivateKeyword), Token(SyntaxKind.ReadOnlyKeyword)))
+ );
+ constructorParams = constructorParams.AddParameters(
+ Parameter(Identifier("handleInitialValue"))
+ .WithType(DelegateHelpers.CreateAsyncFunc(responseType, true, requestType, item.Capability.Syntax))
+ );
+ }
}
else
{
@@ -512,49 +549,81 @@ private TypeDeclarationSyntax CreateDelegatingPartialHandler(RequestItem item, R
Parameter(Identifier("handleResolve"))
.WithType(DelegateHelpers.CreateAsyncFunc(resolveType, true, resolveType))
);
+ if (item is { PartialHasInitialValue: true })
+ {
+ handler = handler.AddMembers(
+ FieldDeclaration(
+ VariableDeclaration(DelegateHelpers.CreateAsyncFunc(responseType, true, requestType))
+ .WithVariables(SingletonSeparatedList(VariableDeclarator(Identifier("_handleInitialValue"))))
+ )
+ .WithModifiers(TokenList(Token(SyntaxKind.PrivateKeyword), Token(SyntaxKind.ReadOnlyKeyword)))
+ );
+ constructorParams = constructorParams.AddParameters(
+ Parameter(Identifier("handleInitialValue"))
+ .WithType(DelegateHelpers.CreateAsyncFunc(responseType, true, requestType))
+ );
+ }
}
- handler = handler.AddMembers(
- ConstructorDeclaration(Identifier($"Delegating{item.JsonRpcAttributes.HandlerName}PartialHandler"))
- .WithModifiers(TokenList(Token(SyntaxKind.PublicKeyword)))
- .WithParameterList(constructorParams)
- .WithInitializer(
- ConstructorInitializer(
- SyntaxKind.BaseConstructorInitializer,
- ArgumentList(SingletonSeparatedList(Argument(IdentifierName("progressManager"))))
- )
- )
- .WithBody(
- Block(
- ExpressionStatement(
- AssignmentExpression(
- SyntaxKind.SimpleAssignmentExpression,
- IdentifierName("_registrationOptionsFactory"),
- IdentifierName("registrationOptionsFactory")
- )
- ),
- ExpressionStatement(
- AssignmentExpression(
- SyntaxKind.SimpleAssignmentExpression,
- IdentifierName("_handle"),
- IdentifierName("handle")
- )
- ),
- ExpressionStatement(
- AssignmentExpression(
- SyntaxKind.SimpleAssignmentExpression,
- IdentifierName("_handleResolve"),
- IdentifierName("handleResolve")
- )
+ var constructorDeclaration = ConstructorDeclaration(Identifier($"Delegating{item.JsonRpcAttributes.HandlerName}PartialHandler"))
+ .WithModifiers(TokenList(Token(SyntaxKind.PublicKeyword)))
+ .WithParameterList(constructorParams)
+ .WithInitializer(
+ ConstructorInitializer(
+ SyntaxKind.BaseConstructorInitializer,
+ ArgumentList(SingletonSeparatedList(Argument(IdentifierName("progressManager"))))
+ )
+ )
+ .WithBody(
+ Block(
+ ExpressionStatement(
+ AssignmentExpression(
+ SyntaxKind.SimpleAssignmentExpression,
+ IdentifierName("_registrationOptionsFactory"),
+ IdentifierName("registrationOptionsFactory")
+ )
+ ),
+ ExpressionStatement(
+ AssignmentExpression(
+ SyntaxKind.SimpleAssignmentExpression,
+ IdentifierName("_handle"),
+ IdentifierName("handle")
+ )
+ ),
+ ExpressionStatement(
+ AssignmentExpression(
+ SyntaxKind.SimpleAssignmentExpression,
+ IdentifierName("_handleResolve"),
+ IdentifierName("handleResolve")
+ )
+ )
+ )
+ );
+
+ if (item is { PartialHasInitialValue: true })
+ {
+ constructorDeclaration = constructorDeclaration.WithBody(
+ constructorDeclaration.Body!.AddStatements(
+ ExpressionStatement(
+ AssignmentExpression(
+ SyntaxKind.SimpleAssignmentExpression,
+ IdentifierName("_handleInitialValue"),
+ IdentifierName("handleInitialValue")
)
)
- ),
+ )
+ );
+ }
+
+ handler = handler.AddMembers(
+ constructorDeclaration,
MethodDeclaration(PredefinedType(Token(SyntaxKind.VoidKeyword)), Identifier("Handle"))
.WithModifiers(TokenList(Token(SyntaxKind.ProtectedKeyword), Token(SyntaxKind.OverrideKeyword)))
.WithParameterList(
ParameterList(
SeparatedList(
- new[] {
+ new[]
+ {
Parameter(Identifier("request")).WithType(requestType),
Parameter(Identifier("results")).WithType(observerType),
Parameter(Identifier("cancellationToken")).WithType(IdentifierName("CancellationToken"))
@@ -569,13 +638,15 @@ private TypeDeclarationSyntax CreateDelegatingPartialHandler(RequestItem item, R
ArgumentList(
SeparatedList(
item.Capability is { }
- ? new[] {
+ ? new[]
+ {
Argument(IdentifierName("request")),
Argument(IdentifierName("results")),
Argument(IdentifierName("Capability")),
Argument(IdentifierName("cancellationToken"))
}
- : new[] {
+ : new[]
+ {
Argument(IdentifierName("request")),
Argument(IdentifierName("results")),
Argument(IdentifierName("cancellationToken"))
@@ -585,9 +656,7 @@ item.Capability is { }
)
)
)
- .WithSemicolonToken(Token(SyntaxKind.SemicolonToken))
- );
- handler = handler.AddMembers(
+ .WithSemicolonToken(Token(SyntaxKind.SemicolonToken)),
MethodDeclaration(
GenericName(Identifier("Task"))
.WithTypeArgumentList(TypeArgumentList(SingletonSeparatedList(resolveType))),
@@ -597,7 +666,8 @@ item.Capability is { }
.WithParameterList(
ParameterList(
SeparatedList(
- new[] {
+ new[]
+ {
Parameter(Identifier("request")).WithType(resolveType),
Parameter(Identifier("cancellationToken")).WithType(IdentifierName("CancellationToken"))
}
@@ -611,12 +681,14 @@ item.Capability is { }
ArgumentList(
SeparatedList(
item.Capability is { }
- ? new[] {
+ ? new[]
+ {
Argument(IdentifierName("request")),
Argument(IdentifierName("Capability")),
Argument(IdentifierName("cancellationToken"))
}
- : new[] {
+ : new[]
+ {
Argument(IdentifierName("request")),
Argument(IdentifierName("cancellationToken"))
}
@@ -627,6 +699,71 @@ item.Capability is { }
)
.WithSemicolonToken(Token(SyntaxKind.SemicolonToken))
);
+ if (item is { PartialHasInitialValue: true })
+ {
+ handler = handler.AddMembers(
+ MethodDeclaration(
+ GenericName(Identifier("Task"))
+ .WithTypeArgumentList(TypeArgumentList(SingletonSeparatedList(item.Response.Syntax))),
+ Identifier("HandleInitialValue")
+ )
+ .WithModifiers(TokenList(Token(SyntaxKind.ProtectedKeyword), Token(SyntaxKind.OverrideKeyword), Token(SyntaxKind.AsyncKeyword)))
+ .WithParameterList(
+ ParameterList(
+ SeparatedList(
+ new[]
+ {
+ Parameter(Identifier("request")).WithType(requestType),
+ Parameter(Identifier("cancellationToken")).WithType(IdentifierName("CancellationToken"))
+ }
+ )
+ )
+ )
+ .WithExpressionBody(
+ ArrowExpressionClause(
+ AwaitExpression(
+ InvocationExpression(
+ MemberAccessExpression(
+ SyntaxKind.SimpleMemberAccessExpression,
+ InvocationExpression(IdentifierName("_handleInitialValue"))
+ .WithArgumentList(
+ ArgumentList(
+ SeparatedList(
+ item.Capability is { }
+ ? new[]
+ {
+ Argument(IdentifierName("request")),
+ Argument(IdentifierName("Capability")),
+ Argument(IdentifierName("cancellationToken"))
+ }
+ : new[]
+ {
+ Argument(IdentifierName("request")),
+ Argument(IdentifierName("cancellationToken"))
+ }
+ )
+ )
+ ),
+ IdentifierName("ConfigureAwait")
+ )
+ )
+ .WithArgumentList(
+ ArgumentList(
+ SingletonSeparatedList(
+ Argument(
+ LiteralExpression(
+ SyntaxKind.FalseLiteralExpression
+ )
+ )
+ )
+ )
+ )
+ )
+ )
+ )
+ .WithSemicolonToken(Token(SyntaxKind.SemicolonToken))
+ );
+ }
return handler;
diff --git a/src/JsonRpc.Generators/StronglyTypedGenerator.cs b/src/JsonRpc.Generators/StronglyTypedGenerator.cs
index 299cd4f25..2ef2d9f0f 100644
--- a/src/JsonRpc.Generators/StronglyTypedGenerator.cs
+++ b/src/JsonRpc.Generators/StronglyTypedGenerator.cs
@@ -1,10 +1,12 @@
using System.Collections.Generic;
+using System.Collections.Immutable;
using System.IO;
using System.Linq;
using System.Text;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
+using Microsoft.CodeAnalysis.Operations;
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
using static OmniSharp.Extensions.JsonRpc.Generators.Helpers;
@@ -47,6 +49,15 @@ TypeDeclarationSyntax typeDeclarationSyntax and (ClassDeclarationSyntax or Recor
}, (syntaxContext, _) => syntaxContext
);
+ var typedParamsCandidatesSyntaxProvider = context.SyntaxProvider.CreateSyntaxProvider(
+ (syntaxNode, _) => syntaxNode switch
+ {
+ TypeDeclarationSyntax typeDeclarationSyntax and (ClassDeclarationSyntax or RecordDeclarationSyntax) when typeDeclarationSyntax
+ .AttributeLists.ContainsAttribute("GenerateRequestMethods") => true,
+ _ => false
+ }, (syntaxContext, _) => syntaxContext
+ );
+
var canBeResolvedSyntaxProvider = context.SyntaxProvider.CreateSyntaxProvider(
(syntaxNode, _) =>
syntaxNode is TypeDeclarationSyntax { BaseList: { } } typeDeclarationSyntax and (ClassDeclarationSyntax or RecordDeclarationSyntax)
@@ -67,6 +78,18 @@ TypeDeclarationSyntax typeDeclarationSyntax and (ClassDeclarationSyntax or Recor
context.RegisterSourceOutput(createContainersSyntaxProvider.Combine(attributes), GenerateContainerClass);
context.RegisterSourceOutput(canBeResolvedSyntaxProvider.Combine(attributes), GenerateCanBeResolvedClass);
context.RegisterSourceOutput(canHaveDataSyntaxProvider.Combine(attributes), GenerateCanHaveDataClass);
+ // TODO: Add support for generating handler methods and interfaces that take in the strongly typed data.
+// context.RegisterSourceOutput(
+// typedParamsCandidatesSyntaxProvider
+// .Combine(canBeResolvedSyntaxProvider.Select((z, _) => (TypeDeclarationSyntax)z.Node).Collect())
+// .Combine(canHaveDataSyntaxProvider.Select((z, _) => (TypeDeclarationSyntax)z.Node).Collect())
+// .Combine(createContainersSyntaxProvider.Select((z, _) => (TypeDeclarationSyntax)z.Node).Collect())
+// .Select(
+// (tuple, token) => ( candidate: tuple.Left.Left.Left,
+// resolvedItems: tuple.Left.Left.Right.Concat(tuple.Left.Right).Concat(tuple.Right).ToImmutableArray() )
+// ),
+// GenerateTypedParams
+// );
}
private void GenerateContainerClass(SourceProductionContext context, (GeneratorSyntaxContext syntaxContext, AttributeData attributeData) valueTuple)
@@ -221,62 +244,68 @@ bool includeHandlerIdentity
if (container is { })
{
var containerName = container is { ConstructorArguments: { Length: > 0 } arguments } ? arguments[0].Value as string : null;
+
var typedContainer = CreateContainerClass(typedClass, containerName)
.WithHandlerIdentityConstraint(includeHandlerIdentity);
var typedArgumentList = TypeArgumentList(SingletonSeparatedList(IdentifierName("T")));
- typedContainer = typedContainer
- .AddMembers(
- ConversionOperatorDeclaration(Token(SyntaxKind.ImplicitKeyword), IdentifierName(typedContainer.Identifier))
- .WithModifiers(TokenList(Token(SyntaxKind.PublicKeyword), Token(SyntaxKind.StaticKeyword)))
- .WithParameterList(
- ParameterList(
- SingletonSeparatedList(
- Parameter(Identifier("container"))
- .WithType(GenericName(typedContainer.Identifier).WithTypeArgumentList(typedArgumentList))
+
+ if (!( container is { NamedArguments: { Length: > 0 } namedArguments }
+ && namedArguments.FirstOrDefault(z => z.Key == "GenerateImplicitConversion") is { Value.Value: false } ))
+ {
+ typedContainer = typedContainer
+ .AddMembers(
+ ConversionOperatorDeclaration(Token(SyntaxKind.ImplicitKeyword), IdentifierName(typedContainer.Identifier))
+ .WithModifiers(TokenList(Token(SyntaxKind.PublicKeyword), Token(SyntaxKind.StaticKeyword)))
+ .WithParameterList(
+ ParameterList(
+ SingletonSeparatedList(
+ Parameter(Identifier("container"))
+ .WithType(GenericName(typedContainer.Identifier).WithTypeArgumentList(typedArgumentList))
+ )
)
)
- )
- .WithExpressionBody(
- ArrowExpressionClause(
- ObjectCreationExpression(IdentifierName(typedContainer.Identifier))
- .WithArgumentList(
- ArgumentList(
- SingletonSeparatedList(
- Argument(
- InvocationExpression(
- MemberAccessExpression(
- SyntaxKind.SimpleMemberAccessExpression,
- IdentifierName("container"),
- IdentifierName("Select")
+ .WithExpressionBody(
+ ArrowExpressionClause(
+ ObjectCreationExpression(IdentifierName(typedContainer.Identifier))
+ .WithArgumentList(
+ ArgumentList(
+ SingletonSeparatedList(
+ Argument(
+ InvocationExpression(
+ MemberAccessExpression(
+ SyntaxKind.SimpleMemberAccessExpression,
+ IdentifierName("container"),
+ IdentifierName("Select")
+ )
)
- )
- .WithArgumentList(
- ArgumentList(
- SingletonSeparatedList(
- Argument(
- SimpleLambdaExpression(Parameter(Identifier("value")))
- .WithExpressionBody(
- CastExpression(
- IdentifierName(candidate.Identifier),
- IdentifierName("value")
+ .WithArgumentList(
+ ArgumentList(
+ SingletonSeparatedList(
+ Argument(
+ SimpleLambdaExpression(Parameter(Identifier("value")))
+ .WithExpressionBody(
+ CastExpression(
+ IdentifierName(candidate.Identifier),
+ IdentifierName("value")
+ )
)
- )
+ )
)
)
)
- )
+ )
)
)
)
- )
+ )
)
- )
- .MakeMethodNullable(IdentifierName("container"))
- .WithSemicolonToken(
- Token(SyntaxKind.SemicolonToken)
- )
- );
+ .MakeMethodNullable(IdentifierName("container"))
+ .WithSemicolonToken(
+ Token(SyntaxKind.SemicolonToken)
+ )
+ );
+ }
compilationMembers.Add(typedContainer);
}
diff --git a/src/JsonRpc/JsonRpc.csproj b/src/JsonRpc/JsonRpc.csproj
index 29782f6dc..efa5b2beb 100644
--- a/src/JsonRpc/JsonRpc.csproj
+++ b/src/JsonRpc/JsonRpc.csproj
@@ -17,67 +17,48 @@
-
+
- <_Parameter1
- >OmniSharp.Extensions.LanguageProtocol.Testing, PublicKey=0024000004800000940000000602000000240000525341310004000001000100391db875e68eb4bfef49ce14313b9e13f2cd3cc89eb273bbe6c11a55044c7d4f566cf092e1c77ef9e7c75b1496ae7f95d925938f5a01793dd8d9f99ae0a7595779b71b971287d7d7b5960d052078d14f5ce1a85ea5c9fb2f59ac735ff7bc215cab469b7c3486006860bad6f4c3b5204ea2f28dd4e1d05e2cca462cfd593b9f9f
+ <_Parameter1>OmniSharp.Extensions.LanguageProtocol.Testing, PublicKey=0024000004800000940000000602000000240000525341310004000001000100391db875e68eb4bfef49ce14313b9e13f2cd3cc89eb273bbe6c11a55044c7d4f566cf092e1c77ef9e7c75b1496ae7f95d925938f5a01793dd8d9f99ae0a7595779b71b971287d7d7b5960d052078d14f5ce1a85ea5c9fb2f59ac735ff7bc215cab469b7c3486006860bad6f4c3b5204ea2f28dd4e1d05e2cca462cfd593b9f9f
- <_Parameter1
- >OmniSharp.Extensions.DebugAdapter.Testing, PublicKey=0024000004800000940000000602000000240000525341310004000001000100391db875e68eb4bfef49ce14313b9e13f2cd3cc89eb273bbe6c11a55044c7d4f566cf092e1c77ef9e7c75b1496ae7f95d925938f5a01793dd8d9f99ae0a7595779b71b971287d7d7b5960d052078d14f5ce1a85ea5c9fb2f59ac735ff7bc215cab469b7c3486006860bad6f4c3b5204ea2f28dd4e1d05e2cca462cfd593b9f9f
+ <_Parameter1>OmniSharp.Extensions.DebugAdapter.Testing, PublicKey=0024000004800000940000000602000000240000525341310004000001000100391db875e68eb4bfef49ce14313b9e13f2cd3cc89eb273bbe6c11a55044c7d4f566cf092e1c77ef9e7c75b1496ae7f95d925938f5a01793dd8d9f99ae0a7595779b71b971287d7d7b5960d052078d14f5ce1a85ea5c9fb2f59ac735ff7bc215cab469b7c3486006860bad6f4c3b5204ea2f28dd4e1d05e2cca462cfd593b9f9f
- <_Parameter1
- >OmniSharp.Extensions.JsonRpc.Testing, PublicKey=0024000004800000940000000602000000240000525341310004000001000100391db875e68eb4bfef49ce14313b9e13f2cd3cc89eb273bbe6c11a55044c7d4f566cf092e1c77ef9e7c75b1496ae7f95d925938f5a01793dd8d9f99ae0a7595779b71b971287d7d7b5960d052078d14f5ce1a85ea5c9fb2f59ac735ff7bc215cab469b7c3486006860bad6f4c3b5204ea2f28dd4e1d05e2cca462cfd593b9f9f
+ <_Parameter1>OmniSharp.Extensions.JsonRpc.Testing, PublicKey=0024000004800000940000000602000000240000525341310004000001000100391db875e68eb4bfef49ce14313b9e13f2cd3cc89eb273bbe6c11a55044c7d4f566cf092e1c77ef9e7c75b1496ae7f95d925938f5a01793dd8d9f99ae0a7595779b71b971287d7d7b5960d052078d14f5ce1a85ea5c9fb2f59ac735ff7bc215cab469b7c3486006860bad6f4c3b5204ea2f28dd4e1d05e2cca462cfd593b9f9f
- <_Parameter1
- >OmniSharp.Extensions.LanguageServer, PublicKey=0024000004800000940000000602000000240000525341310004000001000100391db875e68eb4bfef49ce14313b9e13f2cd3cc89eb273bbe6c11a55044c7d4f566cf092e1c77ef9e7c75b1496ae7f95d925938f5a01793dd8d9f99ae0a7595779b71b971287d7d7b5960d052078d14f5ce1a85ea5c9fb2f59ac735ff7bc215cab469b7c3486006860bad6f4c3b5204ea2f28dd4e1d05e2cca462cfd593b9f9f
+ <_Parameter1>OmniSharp.Extensions.LanguageServer, PublicKey=0024000004800000940000000602000000240000525341310004000001000100391db875e68eb4bfef49ce14313b9e13f2cd3cc89eb273bbe6c11a55044c7d4f566cf092e1c77ef9e7c75b1496ae7f95d925938f5a01793dd8d9f99ae0a7595779b71b971287d7d7b5960d052078d14f5ce1a85ea5c9fb2f59ac735ff7bc215cab469b7c3486006860bad6f4c3b5204ea2f28dd4e1d05e2cca462cfd593b9f9f
- <_Parameter1
- >OmniSharp.Extensions.LanguageProtocol, PublicKey=0024000004800000940000000602000000240000525341310004000001000100391db875e68eb4bfef49ce14313b9e13f2cd3cc89eb273bbe6c11a55044c7d4f566cf092e1c77ef9e7c75b1496ae7f95d925938f5a01793dd8d9f99ae0a7595779b71b971287d7d7b5960d052078d14f5ce1a85ea5c9fb2f59ac735ff7bc215cab469b7c3486006860bad6f4c3b5204ea2f28dd4e1d05e2cca462cfd593b9f9f
+ <_Parameter1>OmniSharp.Extensions.LanguageProtocol, PublicKey=0024000004800000940000000602000000240000525341310004000001000100391db875e68eb4bfef49ce14313b9e13f2cd3cc89eb273bbe6c11a55044c7d4f566cf092e1c77ef9e7c75b1496ae7f95d925938f5a01793dd8d9f99ae0a7595779b71b971287d7d7b5960d052078d14f5ce1a85ea5c9fb2f59ac735ff7bc215cab469b7c3486006860bad6f4c3b5204ea2f28dd4e1d05e2cca462cfd593b9f9f
- <_Parameter1
- >OmniSharp.Extensions.LanguageProtocol.Proposals, PublicKey=0024000004800000940000000602000000240000525341310004000001000100391db875e68eb4bfef49ce14313b9e13f2cd3cc89eb273bbe6c11a55044c7d4f566cf092e1c77ef9e7c75b1496ae7f95d925938f5a01793dd8d9f99ae0a7595779b71b971287d7d7b5960d052078d14f5ce1a85ea5c9fb2f59ac735ff7bc215cab469b7c3486006860bad6f4c3b5204ea2f28dd4e1d05e2cca462cfd593b9f9f
+ <_Parameter1>OmniSharp.Extensions.LanguageProtocol.Proposals, PublicKey=0024000004800000940000000602000000240000525341310004000001000100391db875e68eb4bfef49ce14313b9e13f2cd3cc89eb273bbe6c11a55044c7d4f566cf092e1c77ef9e7c75b1496ae7f95d925938f5a01793dd8d9f99ae0a7595779b71b971287d7d7b5960d052078d14f5ce1a85ea5c9fb2f59ac735ff7bc215cab469b7c3486006860bad6f4c3b5204ea2f28dd4e1d05e2cca462cfd593b9f9f
- <_Parameter1
- >OmniSharp.Extensions.LanguageServer.Shared, PublicKey=0024000004800000940000000602000000240000525341310004000001000100391db875e68eb4bfef49ce14313b9e13f2cd3cc89eb273bbe6c11a55044c7d4f566cf092e1c77ef9e7c75b1496ae7f95d925938f5a01793dd8d9f99ae0a7595779b71b971287d7d7b5960d052078d14f5ce1a85ea5c9fb2f59ac735ff7bc215cab469b7c3486006860bad6f4c3b5204ea2f28dd4e1d05e2cca462cfd593b9f9f
+ <_Parameter1>OmniSharp.Extensions.LanguageServer.Shared, PublicKey=0024000004800000940000000602000000240000525341310004000001000100391db875e68eb4bfef49ce14313b9e13f2cd3cc89eb273bbe6c11a55044c7d4f566cf092e1c77ef9e7c75b1496ae7f95d925938f5a01793dd8d9f99ae0a7595779b71b971287d7d7b5960d052078d14f5ce1a85ea5c9fb2f59ac735ff7bc215cab469b7c3486006860bad6f4c3b5204ea2f28dd4e1d05e2cca462cfd593b9f9f
- <_Parameter1
- >OmniSharp.Extensions.LanguageClient, PublicKey=0024000004800000940000000602000000240000525341310004000001000100391db875e68eb4bfef49ce14313b9e13f2cd3cc89eb273bbe6c11a55044c7d4f566cf092e1c77ef9e7c75b1496ae7f95d925938f5a01793dd8d9f99ae0a7595779b71b971287d7d7b5960d052078d14f5ce1a85ea5c9fb2f59ac735ff7bc215cab469b7c3486006860bad6f4c3b5204ea2f28dd4e1d05e2cca462cfd593b9f9f
+ <_Parameter1>OmniSharp.Extensions.LanguageClient, PublicKey=0024000004800000940000000602000000240000525341310004000001000100391db875e68eb4bfef49ce14313b9e13f2cd3cc89eb273bbe6c11a55044c7d4f566cf092e1c77ef9e7c75b1496ae7f95d925938f5a01793dd8d9f99ae0a7595779b71b971287d7d7b5960d052078d14f5ce1a85ea5c9fb2f59ac735ff7bc215cab469b7c3486006860bad6f4c3b5204ea2f28dd4e1d05e2cca462cfd593b9f9f
- <_Parameter1
- >OmniSharp.Extensions.DebugAdapter.Server, PublicKey=0024000004800000940000000602000000240000525341310004000001000100391db875e68eb4bfef49ce14313b9e13f2cd3cc89eb273bbe6c11a55044c7d4f566cf092e1c77ef9e7c75b1496ae7f95d925938f5a01793dd8d9f99ae0a7595779b71b971287d7d7b5960d052078d14f5ce1a85ea5c9fb2f59ac735ff7bc215cab469b7c3486006860bad6f4c3b5204ea2f28dd4e1d05e2cca462cfd593b9f9f
+ <_Parameter1>OmniSharp.Extensions.DebugAdapter.Server, PublicKey=0024000004800000940000000602000000240000525341310004000001000100391db875e68eb4bfef49ce14313b9e13f2cd3cc89eb273bbe6c11a55044c7d4f566cf092e1c77ef9e7c75b1496ae7f95d925938f5a01793dd8d9f99ae0a7595779b71b971287d7d7b5960d052078d14f5ce1a85ea5c9fb2f59ac735ff7bc215cab469b7c3486006860bad6f4c3b5204ea2f28dd4e1d05e2cca462cfd593b9f9f
- <_Parameter1
- >OmniSharp.Extensions.DebugAdapter.Client, PublicKey=0024000004800000940000000602000000240000525341310004000001000100391db875e68eb4bfef49ce14313b9e13f2cd3cc89eb273bbe6c11a55044c7d4f566cf092e1c77ef9e7c75b1496ae7f95d925938f5a01793dd8d9f99ae0a7595779b71b971287d7d7b5960d052078d14f5ce1a85ea5c9fb2f59ac735ff7bc215cab469b7c3486006860bad6f4c3b5204ea2f28dd4e1d05e2cca462cfd593b9f9f
+ <_Parameter1>OmniSharp.Extensions.DebugAdapter.Client, PublicKey=0024000004800000940000000602000000240000525341310004000001000100391db875e68eb4bfef49ce14313b9e13f2cd3cc89eb273bbe6c11a55044c7d4f566cf092e1c77ef9e7c75b1496ae7f95d925938f5a01793dd8d9f99ae0a7595779b71b971287d7d7b5960d052078d14f5ce1a85ea5c9fb2f59ac735ff7bc215cab469b7c3486006860bad6f4c3b5204ea2f28dd4e1d05e2cca462cfd593b9f9f
- <_Parameter1
- >OmniSharp.Extensions.DebugAdapter.Shared, PublicKey=0024000004800000940000000602000000240000525341310004000001000100391db875e68eb4bfef49ce14313b9e13f2cd3cc89eb273bbe6c11a55044c7d4f566cf092e1c77ef9e7c75b1496ae7f95d925938f5a01793dd8d9f99ae0a7595779b71b971287d7d7b5960d052078d14f5ce1a85ea5c9fb2f59ac735ff7bc215cab469b7c3486006860bad6f4c3b5204ea2f28dd4e1d05e2cca462cfd593b9f9f
+ <_Parameter1>OmniSharp.Extensions.DebugAdapter.Shared, PublicKey=0024000004800000940000000602000000240000525341310004000001000100391db875e68eb4bfef49ce14313b9e13f2cd3cc89eb273bbe6c11a55044c7d4f566cf092e1c77ef9e7c75b1496ae7f95d925938f5a01793dd8d9f99ae0a7595779b71b971287d7d7b5960d052078d14f5ce1a85ea5c9fb2f59ac735ff7bc215cab469b7c3486006860bad6f4c3b5204ea2f28dd4e1d05e2cca462cfd593b9f9f
- <_Parameter1
- >OmniSharp.Extensions.DebugAdapter, PublicKey=0024000004800000940000000602000000240000525341310004000001000100391db875e68eb4bfef49ce14313b9e13f2cd3cc89eb273bbe6c11a55044c7d4f566cf092e1c77ef9e7c75b1496ae7f95d925938f5a01793dd8d9f99ae0a7595779b71b971287d7d7b5960d052078d14f5ce1a85ea5c9fb2f59ac735ff7bc215cab469b7c3486006860bad6f4c3b5204ea2f28dd4e1d05e2cca462cfd593b9f9f
+ <_Parameter1>OmniSharp.Extensions.DebugAdapter, PublicKey=0024000004800000940000000602000000240000525341310004000001000100391db875e68eb4bfef49ce14313b9e13f2cd3cc89eb273bbe6c11a55044c7d4f566cf092e1c77ef9e7c75b1496ae7f95d925938f5a01793dd8d9f99ae0a7595779b71b971287d7d7b5960d052078d14f5ce1a85ea5c9fb2f59ac735ff7bc215cab469b7c3486006860bad6f4c3b5204ea2f28dd4e1d05e2cca462cfd593b9f9f
- <_Parameter1
- >OmniSharp.Extensions.DebugAdapter.Proposals, PublicKey=0024000004800000940000000602000000240000525341310004000001000100391db875e68eb4bfef49ce14313b9e13f2cd3cc89eb273bbe6c11a55044c7d4f566cf092e1c77ef9e7c75b1496ae7f95d925938f5a01793dd8d9f99ae0a7595779b71b971287d7d7b5960d052078d14f5ce1a85ea5c9fb2f59ac735ff7bc215cab469b7c3486006860bad6f4c3b5204ea2f28dd4e1d05e2cca462cfd593b9f9f
+ <_Parameter1>OmniSharp.Extensions.DebugAdapter.Proposals, PublicKey=0024000004800000940000000602000000240000525341310004000001000100391db875e68eb4bfef49ce14313b9e13f2cd3cc89eb273bbe6c11a55044c7d4f566cf092e1c77ef9e7c75b1496ae7f95d925938f5a01793dd8d9f99ae0a7595779b71b971287d7d7b5960d052078d14f5ce1a85ea5c9fb2f59ac735ff7bc215cab469b7c3486006860bad6f4c3b5204ea2f28dd4e1d05e2cca462cfd593b9f9f
diff --git a/src/JsonRpc/Server/ErrorCodes.cs b/src/JsonRpc/Server/ErrorCodes.cs
index a33a53c7f..99bfcb5a0 100644
--- a/src/JsonRpc/Server/ErrorCodes.cs
+++ b/src/JsonRpc/Server/ErrorCodes.cs
@@ -51,8 +51,25 @@ public static class ErrorCodes
public const int RequestCancelled = -32800;
///
- /// Request was cancelled.
+ /// Content was modified
///
public const int ContentModified = -32801;
+
+ ///
+ /// A request failed but it was syntactically correct, e.g the
+ /// method name was known and the parameters were valid. The error
+ /// message should contain human readable information about why
+ /// the request failed.
+ /// @since 3.17.0
+ ///
+ public const int RequestFailed = -32803;
+
+ ///
+ /// The server cancelled the request. This error code should
+ /// only be used for requests that explicitly support being
+ /// server cancellable.
+ /// @since 3.17.0
+ ///
+ public const int ServerCancelled = -32802;
}
}
diff --git a/src/JsonRpc/Server/RequestFailedException.cs b/src/JsonRpc/Server/RequestFailedException.cs
new file mode 100644
index 000000000..8ea568a5f
--- /dev/null
+++ b/src/JsonRpc/Server/RequestFailedException.cs
@@ -0,0 +1,87 @@
+using System.Runtime.Serialization;
+
+namespace OmniSharp.Extensions.JsonRpc.Server;
+
+///
+/// Exception raised when request parameters are invalid according to the target method.
+///
+[Serializable]
+public class RequestFailedException
+ : TaskCanceledException, IRequestException
+{
+ ///
+ /// Create a new .
+ ///
+ ///
+ /// The LSP / JSON-RPC request Id (if known).
+ ///
+ public RequestFailedException(object? requestId)
+ : this(ErrorCodes.RequestFailed, requestId?.ToString() ?? "(unknown)", "Content not modified.", null!)
+ {
+ }
+
+ ///
+ /// Create a new .
+ ///
+ ///
+ /// The LSP / JSON-RPC request Id (if known).
+ ///
+ ///
+ /// The exception that caused this exception to be raised.
+ ///
+ public RequestFailedException(object? requestId, Exception inner)
+ : this(ErrorCodes.RequestFailed, requestId?.ToString() ?? "(unknown)", "Content not modified.", inner)
+ {
+ }
+
+ ///
+ /// Create a new .
+ ///
+ ///
+ /// The LSP / JSON-RPC error code.
+ ///
+ ///
+ /// The exception message.
+ ///
+ ///
+ /// The LSP / JSON-RPC request Id (if known).
+ ///
+ ///
+ /// The exception that caused this exception to be raised.
+ ///
+ public RequestFailedException(int errorCode, string message, string requestId, Exception inner) : base(message, inner)
+ {
+ RequestId = !string.IsNullOrWhiteSpace(requestId) ? requestId : UnknownRequestId;
+ ErrorCode = errorCode;
+ }
+
+ ///
+ /// Serialisation constructor.
+ ///
+ ///
+ /// The serialisation data-store.
+ ///
+ ///
+ /// The serialisation streaming context.
+ ///
+ protected RequestFailedException(SerializationInfo info, StreamingContext context)
+ {
+ RequestId = info.GetString(nameof(RequestId));
+ ErrorCode = info.GetInt32(nameof(ErrorCode));
+ }
+
+ ///
+ /// The LSP / JSON-RPC request Id (if known).
+ ///
+ public object RequestId { get; }
+
+ ///
+ /// The LSP / JSON-RPC error code.
+ ///
+ public int ErrorCode { get; }
+
+ ///
+ /// The request Id used when no valid request Id was supplied.
+ ///
+ public const string UnknownRequestId = "(unknown)";
+}
diff --git a/src/JsonRpc/Server/ServerCancelledException.cs b/src/JsonRpc/Server/ServerCancelledException.cs
new file mode 100644
index 000000000..8a7338928
--- /dev/null
+++ b/src/JsonRpc/Server/ServerCancelledException.cs
@@ -0,0 +1,87 @@
+using System.Runtime.Serialization;
+
+namespace OmniSharp.Extensions.JsonRpc.Server;
+
+///
+/// Exception raised when request parameters are invalid according to the target method.
+///
+[Serializable]
+public class ServerCancelledException
+ : TaskCanceledException, IRequestException
+{
+ ///
+ /// Create a new .
+ ///
+ ///
+ /// The LSP / JSON-RPC request Id (if known).
+ ///
+ public ServerCancelledException(object? requestId)
+ : this(ErrorCodes.ServerCancelled, requestId?.ToString() ?? "(unknown)", "Content not modified.", null!)
+ {
+ }
+
+ ///
+ /// Create a new .
+ ///
+ ///
+ /// The LSP / JSON-RPC request Id (if known).
+ ///
+ ///
+ /// The exception that caused this exception to be raised.
+ ///
+ public ServerCancelledException(object? requestId, Exception inner)
+ : this(ErrorCodes.ServerCancelled, requestId?.ToString() ?? "(unknown)", "Content not modified.", inner)
+ {
+ }
+
+ ///
+ /// Create a new .
+ ///
+ ///
+ /// The LSP / JSON-RPC error code.
+ ///
+ ///
+ /// The exception message.
+ ///
+ ///
+ /// The LSP / JSON-RPC request Id (if known).
+ ///
+ ///
+ /// The exception that caused this exception to be raised.
+ ///
+ public ServerCancelledException(int errorCode, string message, string requestId, Exception inner) : base(message, inner)
+ {
+ RequestId = !string.IsNullOrWhiteSpace(requestId) ? requestId : UnknownRequestId;
+ ErrorCode = errorCode;
+ }
+
+ ///
+ /// Serialisation constructor.
+ ///
+ ///
+ /// The serialisation data-store.
+ ///
+ ///
+ /// The serialisation streaming context.
+ ///
+ protected ServerCancelledException(SerializationInfo info, StreamingContext context)
+ {
+ RequestId = info.GetString(nameof(RequestId));
+ ErrorCode = info.GetInt32(nameof(ErrorCode));
+ }
+
+ ///
+ /// The LSP / JSON-RPC request Id (if known).
+ ///
+ public object RequestId { get; }
+
+ ///
+ /// The LSP / JSON-RPC error code.
+ ///
+ public int ErrorCode { get; }
+
+ ///
+ /// The request Id used when no valid request Id was supplied.
+ ///
+ public const string UnknownRequestId = "(unknown)";
+}
diff --git a/src/Protocol/AbstractHandlers.Base.cs b/src/Protocol/AbstractHandlers.Base.cs
new file mode 100644
index 000000000..739ff577b
--- /dev/null
+++ b/src/Protocol/AbstractHandlers.Base.cs
@@ -0,0 +1,79 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reactive.Linq;
+using System.Reactive.Subjects;
+using System.Reactive.Threading.Tasks;
+using System.Threading;
+using System.Threading.Tasks;
+using MediatR;
+using OmniSharp.Extensions.JsonRpc;
+using OmniSharp.Extensions.LanguageServer.Protocol.Client.Capabilities;
+using OmniSharp.Extensions.LanguageServer.Protocol.Models;
+using OmniSharp.Extensions.LanguageServer.Protocol.Progress;
+
+namespace OmniSharp.Extensions.LanguageServer.Protocol
+{
+ public static partial class AbstractHandlers
+ {
+ public abstract class Base :
+ IRegistration,
+ ICapability
+ where TRegistrationOptions : class, new()
+ where TCapability : ICapability
+ {
+ protected TRegistrationOptions RegistrationOptions { get; private set; } = default!;
+ protected TCapability Capability { get; private set; } = default!;
+ protected ClientCapabilities ClientCapabilities { get; private set; } = default!;
+ protected internal abstract TRegistrationOptions CreateRegistrationOptions(TCapability capability, ClientCapabilities clientCapabilities);
+
+ TRegistrationOptions IRegistration.GetRegistrationOptions(
+ TCapability capability, ClientCapabilities clientCapabilities
+ )
+ {
+ // ReSharper disable twice ConditionIsAlwaysTrueOrFalse
+ if (RegistrationOptions is not null && Capability is not null) return RegistrationOptions;
+ Capability = capability;
+ ClientCapabilities = clientCapabilities;
+ return RegistrationOptions = CreateRegistrationOptions(capability, clientCapabilities);
+ }
+
+ void ICapability.SetCapability(TCapability capability, ClientCapabilities clientCapabilities)
+ {
+ ClientCapabilities = clientCapabilities;
+ Capability = capability;
+ }
+ }
+
+ public abstract class BaseCapability :
+ ICapability
+ where TCapability : ICapability
+ {
+ protected TCapability Capability { get; private set; } = default!;
+ protected ClientCapabilities ClientCapabilities { get; private set; } = default!;
+
+ void ICapability.SetCapability(TCapability capability, ClientCapabilities clientCapabilities)
+ {
+ ClientCapabilities = clientCapabilities;
+ Capability = capability;
+ }
+ }
+
+ public abstract class Base :
+ IRegistration
+ where TRegistrationOptions : class, new()
+ {
+ protected TRegistrationOptions RegistrationOptions { get; private set; } = default!;
+ protected ClientCapabilities ClientCapabilities { get; private set; } = default!;
+ protected abstract TRegistrationOptions CreateRegistrationOptions(ClientCapabilities clientCapabilities);
+
+ TRegistrationOptions IRegistration.GetRegistrationOptions(ClientCapabilities clientCapabilities)
+ {
+ // ReSharper disable once ConditionIsAlwaysTrueOrFalse
+ if (RegistrationOptions is not null) return RegistrationOptions;
+ ClientCapabilities = clientCapabilities;
+ return RegistrationOptions = CreateRegistrationOptions(clientCapabilities);
+ }
+ }
+ }
+}
diff --git a/src/Protocol/AbstractHandlers.Notification.cs b/src/Protocol/AbstractHandlers.Notification.cs
new file mode 100644
index 000000000..89b2c4f36
--- /dev/null
+++ b/src/Protocol/AbstractHandlers.Notification.cs
@@ -0,0 +1,53 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reactive.Linq;
+using System.Reactive.Subjects;
+using System.Reactive.Threading.Tasks;
+using System.Threading;
+using System.Threading.Tasks;
+using MediatR;
+using OmniSharp.Extensions.JsonRpc;
+using OmniSharp.Extensions.LanguageServer.Protocol.Client.Capabilities;
+using OmniSharp.Extensions.LanguageServer.Protocol.Models;
+using OmniSharp.Extensions.LanguageServer.Protocol.Progress;
+
+namespace OmniSharp.Extensions.LanguageServer.Protocol
+{
+ public static partial class AbstractHandlers
+ {
+ public abstract class Notification : IJsonRpcRequestHandler
+ where TParams : IRequest
+ {
+ public abstract Task Handle(TParams request, CancellationToken cancellationToken);
+ }
+
+ public abstract class Notification :
+ Base,
+ IJsonRpcRequestHandler
+ where TParams : IRequest
+ where TRegistrationOptions : class, new()
+ where TCapability : ICapability
+ {
+ public abstract Task Handle(TParams request, CancellationToken cancellationToken);
+ }
+
+ public abstract class Notification :
+ Base,
+ IJsonRpcRequestHandler
+ where TParams : IRequest
+ where TRegistrationOptions : class, new()
+ {
+ public abstract Task Handle(TParams request, CancellationToken cancellationToken);
+ }
+
+ public abstract class NotificationCapability :
+ BaseCapability,
+ IJsonRpcRequestHandler
+ where TParams : IRequest
+ where TCapability : ICapability
+ {
+ public abstract Task Handle(TParams request, CancellationToken cancellationToken);
+ }
+ }
+}
diff --git a/src/Protocol/AbstractHandlers.cs b/src/Protocol/AbstractHandlers.Partial.cs
similarity index 63%
rename from src/Protocol/AbstractHandlers.cs
rename to src/Protocol/AbstractHandlers.Partial.cs
index 4fa7cc9c3..132a470a3 100644
--- a/src/Protocol/AbstractHandlers.cs
+++ b/src/Protocol/AbstractHandlers.Partial.cs
@@ -14,101 +14,8 @@
namespace OmniSharp.Extensions.LanguageServer.Protocol
{
- public static class AbstractHandlers
+ public static partial class AbstractHandlers
{
- public abstract class Base :
- IRegistration,
- ICapability
- where TRegistrationOptions : class, new()
- where TCapability : ICapability
- {
- protected TRegistrationOptions RegistrationOptions { get; private set; } = default!;
- protected TCapability Capability { get; private set; } = default!;
- protected ClientCapabilities ClientCapabilities { get; private set; } = default!;
- protected internal abstract TRegistrationOptions CreateRegistrationOptions(TCapability capability, ClientCapabilities clientCapabilities);
-
- TRegistrationOptions IRegistration.GetRegistrationOptions(TCapability capability, ClientCapabilities clientCapabilities)
- {
- // ReSharper disable twice ConditionIsAlwaysTrueOrFalse
- if (RegistrationOptions is not null && Capability is not null) return RegistrationOptions;
- Capability = capability;
- ClientCapabilities = clientCapabilities;
- return RegistrationOptions = CreateRegistrationOptions(capability, clientCapabilities);
- }
-
- void ICapability.SetCapability(TCapability capability, ClientCapabilities clientCapabilities)
- {
- ClientCapabilities = clientCapabilities;
- Capability = capability;
- }
- }
-
- public abstract class BaseCapability :
- ICapability
- where TCapability : ICapability
- {
- protected TCapability Capability { get; private set; } = default!;
- protected ClientCapabilities ClientCapabilities { get; private set; } = default!;
-
- void ICapability.SetCapability(TCapability capability, ClientCapabilities clientCapabilities)
- {
- ClientCapabilities = clientCapabilities;
- Capability = capability;
- }
- }
-
- public abstract class Base :
- IRegistration
- where TRegistrationOptions : class, new()
- {
- protected TRegistrationOptions RegistrationOptions { get; private set; } = default!;
- protected ClientCapabilities ClientCapabilities { get; private set; } = default!;
- protected abstract TRegistrationOptions CreateRegistrationOptions(ClientCapabilities clientCapabilities);
-
- TRegistrationOptions IRegistration.GetRegistrationOptions(ClientCapabilities clientCapabilities)
- {
- // ReSharper disable once ConditionIsAlwaysTrueOrFalse
- if (RegistrationOptions is not null) return RegistrationOptions;
- ClientCapabilities = clientCapabilities;
- return RegistrationOptions = CreateRegistrationOptions(clientCapabilities);
- }
- }
-
- public abstract class Request :
- IJsonRpcRequestHandler
- where TParams : IRequest
- {
- public abstract Task Handle(TParams request, CancellationToken cancellationToken);
- }
-
- public abstract class Request :
- Base,
- IJsonRpcRequestHandler
- where TParams : IRequest
- where TRegistrationOptions : class, new()
- {
- public abstract Task Handle(TParams request, CancellationToken cancellationToken);
- }
-
- public abstract class Request :
- Base,
- IJsonRpcRequestHandler
- where TParams : IRequest
- where TRegistrationOptions : class, new()
- where TCapability : ICapability
- {
- public abstract Task Handle(TParams request, CancellationToken cancellationToken);
- }
-
- public abstract class RequestCapability :
- BaseCapability,
- IJsonRpcRequestHandler
- where TParams : IRequest
- where TCapability : ICapability
- {
- public abstract Task Handle(TParams request, CancellationToken cancellationToken);
- }
-
public abstract class PartialResult :
Base,
IJsonRpcRequestHandler
@@ -137,10 +44,10 @@ CancellationToken cancellationToken
{
Handle(request, observer, cancellationToken);
await observer;
- return _factory(default(TItem));
+ return default;
}
- var subject = new AsyncSubject();
+ using var subject = new AsyncSubject();
var task = subject
.Select(_factory)
.ToTask(cancellationToken, _progressManager.Scheduler)
@@ -181,10 +88,10 @@ CancellationToken cancellationToken
{
Handle(request, observer, cancellationToken);
await observer;
- return _factory(default);
+ return default;
}
- var subject = new AsyncSubject();
+ using var subject = new AsyncSubject();
var task = subject
.Select(_factory)
.ToTask(cancellationToken, _progressManager.Scheduler)
@@ -225,10 +132,10 @@ CancellationToken cancellationToken
{
Handle(request, observer, cancellationToken);
await observer;
- return _factory(default);
+ return default;
}
- var subject = new AsyncSubject();
+ using var subject = new AsyncSubject();
var task = subject
.Select(_factory)
.ToTask(cancellationToken, _progressManager.Scheduler)
@@ -266,13 +173,14 @@ protected PartialResults(IProgressManager progressManager, Func());
+ return default;
}
- var subject = new Subject>();
+ using var subject = new Subject>();
var task = subject
.Aggregate(
- new List(), (acc, items) => {
+ new List(), (acc, items) =>
+ {
acc.AddRange(items);
return acc;
}
@@ -310,13 +218,14 @@ protected PartialResults(IProgressManager progressManager, Func());
+ return default;
}
- var subject = new Subject>();
+ using var subject = new Subject>();
var task = subject
.Aggregate(
- new List(), (acc, items) => {
+ new List(), (acc, items) =>
+ {
acc.AddRange(items);
return acc;
}
@@ -354,13 +263,14 @@ protected PartialResultsCapability(IProgressManager progressManager, Func());
+ return default;
}
- var subject = new Subject>();
+ using var subject = new Subject>();
var task = subject
.Aggregate(
- new List(), (acc, items) => {
+ new List(), (acc, items) =>
+ {
acc.AddRange(items);
return acc;
}
@@ -375,38 +285,5 @@ protected PartialResultsCapability(IProgressManager progressManager, Func> results, CancellationToken cancellationToken);
}
- public abstract class Notification : IJsonRpcRequestHandler
- where TParams : IRequest
- {
- public abstract Task Handle(TParams request, CancellationToken cancellationToken);
- }
-
- public abstract class Notification :
- Base,
- IJsonRpcRequestHandler
- where TParams : IRequest
- where TRegistrationOptions : class, new()
- where TCapability : ICapability
- {
- public abstract Task Handle(TParams request, CancellationToken cancellationToken);
- }
-
- public abstract class Notification :
- Base,
- IJsonRpcRequestHandler
- where TParams : IRequest
- where TRegistrationOptions : class, new()
- {
- public abstract Task Handle(TParams request, CancellationToken cancellationToken);
- }
-
- public abstract class NotificationCapability :
- BaseCapability,
- IJsonRpcRequestHandler
- where TParams : IRequest
- where TCapability : ICapability
- {
- public abstract Task Handle(TParams request, CancellationToken cancellationToken);
- }
}
}
diff --git a/src/Protocol/AbstractHandlers.PartialWithInitialValue.cs b/src/Protocol/AbstractHandlers.PartialWithInitialValue.cs
new file mode 100644
index 000000000..870020020
--- /dev/null
+++ b/src/Protocol/AbstractHandlers.PartialWithInitialValue.cs
@@ -0,0 +1,295 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reactive.Linq;
+using System.Reactive.Subjects;
+using System.Reactive.Threading.Tasks;
+using System.Threading;
+using System.Threading.Tasks;
+using MediatR;
+using OmniSharp.Extensions.JsonRpc;
+using OmniSharp.Extensions.LanguageServer.Protocol.Client.Capabilities;
+using OmniSharp.Extensions.LanguageServer.Protocol.Models;
+using OmniSharp.Extensions.LanguageServer.Protocol.Progress;
+
+namespace OmniSharp.Extensions.LanguageServer.Protocol
+{
+ public static partial class AbstractHandlers
+ {
+ public abstract class PartialResultWithInitialValue :
+ Base,
+ IJsonRpcRequestHandler
+ where TItem : class?
+ where TParams : IPartialItemWithInitialValueRequest
+ where TResponse : TItem?
+ where TRegistrationOptions : class, new()
+ where TCapability : ICapability
+ {
+ private readonly IProgressManager _progressManager;
+ private readonly Func _factory;
+
+ protected PartialResultWithInitialValue(IProgressManager progressManager,
+ Func factory)
+ {
+ _progressManager = progressManager;
+ _factory = factory;
+ }
+
+ async Task IRequestHandler.Handle(
+ TParams request,
+ CancellationToken cancellationToken
+ )
+ {
+ var observer = _progressManager.For(request, cancellationToken);
+ if (observer != ProgressObserver.Noop)
+ {
+ observer.OnNext(await HandleInitialValue(request, cancellationToken));
+ Handle(request, observer, cancellationToken);
+ await observer;
+ return default;
+ }
+
+ using var subject = new AsyncSubject();
+ var task = subject
+ .Aggregate(await HandleInitialValue(request, cancellationToken), _factory)
+ .ToTask(cancellationToken, _progressManager.Scheduler)
+ .ConfigureAwait(false);
+ // in the event nothing is emitted...
+ subject.OnNext(default!);
+ Handle(request, subject, cancellationToken);
+ return await task;
+ }
+
+ protected abstract Task HandleInitialValue(TParams request, CancellationToken cancellationToken);
+ protected abstract void Handle(TParams request, IObserver results, CancellationToken cancellationToken);
+ }
+
+ public abstract class PartialResultWithInitialValue :
+ Base,
+ IJsonRpcRequestHandler
+ where TItem : class?
+ where TParams : IPartialItemWithInitialValueRequest
+ where TResponse : TItem?
+ where TRegistrationOptions : class, new()
+ {
+ private readonly IProgressManager _progressManager;
+ private readonly Func _factory;
+
+ protected PartialResultWithInitialValue(IProgressManager progressManager,
+ Func factory)
+ {
+ _progressManager = progressManager;
+ _factory = factory;
+ }
+
+ async Task IRequestHandler.Handle(
+ TParams request,
+ CancellationToken cancellationToken
+ )
+ {
+ var observer = _progressManager.For(request, cancellationToken);
+ if (observer != ProgressObserver.Noop)
+ {
+ observer.OnNext(await HandleInitialValue(request, cancellationToken));
+ Handle(request, observer, cancellationToken);
+ await observer;
+ return default;
+ }
+
+ using var subject = new AsyncSubject();
+ var task = subject
+ .Aggregate(await HandleInitialValue(request, cancellationToken), _factory)
+ .ToTask(cancellationToken, _progressManager.Scheduler)
+ .ConfigureAwait(false);
+ // in the event nothing is emitted...
+ subject.OnNext(default!);
+ Handle(request, subject, cancellationToken);
+ return await task;
+ }
+
+ protected abstract Task HandleInitialValue(TParams request, CancellationToken cancellationToken);
+ protected abstract void Handle(TParams request, IObserver results, CancellationToken cancellationToken);
+ }
+
+ public abstract class PartialResultWithInitialValueCapability :
+ BaseCapability,
+ IJsonRpcRequestHandler
+ where TItem : class?
+ where TParams : IPartialItemWithInitialValueRequest
+ where TResponse : TItem?
+ where TCapability : ICapability
+ {
+ private readonly IProgressManager _progressManager;
+ private readonly Func _factory;
+
+ protected PartialResultWithInitialValueCapability(IProgressManager progressManager,
+ Func factory)
+ {
+ _progressManager = progressManager;
+ _factory = factory;
+ }
+
+ async Task IRequestHandler.Handle(
+ TParams request,
+ CancellationToken cancellationToken
+ )
+ {
+ var observer = _progressManager.For(request, cancellationToken);
+ if (observer != ProgressObserver.Noop)
+ {
+ observer.OnNext(await HandleInitialValue(request, cancellationToken));
+ Handle(request, observer, cancellationToken);
+ await observer;
+ return default;
+ }
+
+ using var subject = new AsyncSubject();
+ var task = subject
+ .Aggregate(await HandleInitialValue(request, cancellationToken), _factory)
+ .ToTask(cancellationToken, _progressManager.Scheduler)
+ .ConfigureAwait(false);
+ // in the event nothing is emitted...
+ subject.OnNext(default!);
+ Handle(request, subject, cancellationToken);
+ return await task;
+ }
+
+ protected abstract Task HandleInitialValue(TParams request, CancellationToken cancellationToken);
+ protected abstract void Handle(TParams request, IObserver results, CancellationToken cancellationToken);
+ }
+
+ public abstract class PartialResultsWithInitialValue :
+ Base,
+ IJsonRpcRequestHandler
+ where TParams : IPartialItemsWithInitialValueRequest
+ where TResponse : IEnumerable?
+ where TRegistrationOptions : class, new()
+ where TCapability : ICapability
+ {
+ private readonly IProgressManager _progressManager;
+ private readonly Func, TResponse> _factory;
+
+ protected PartialResultsWithInitialValue(
+ IProgressManager progressManager,
+ Func, TResponse> factory
+ )
+ {
+ _progressManager = progressManager;
+ _factory = factory;
+ }
+
+ async Task IRequestHandler.Handle(TParams request, CancellationToken cancellationToken)
+ {
+ var observer = _progressManager.For(request, cancellationToken);
+ if (observer != ProgressObserver.Noop)
+ {
+ observer.OnNext(await HandleInitialValue(request, cancellationToken));
+ Handle(request, observer, cancellationToken);
+ await observer;
+ return default;
+ }
+
+ {
+ using var subject = new Subject>();
+ var task = subject
+ .Aggregate(await HandleInitialValue(request, cancellationToken), _factory)
+ .ToTask(cancellationToken, _progressManager.Scheduler)
+ .ConfigureAwait(false);
+ Handle(request, subject, cancellationToken);
+ return await task;
+ }
+ }
+
+ protected abstract Task HandleInitialValue(TParams request, CancellationToken cancellationToken);
+ protected abstract void Handle(TParams request, IObserver> results, CancellationToken cancellationToken);
+ }
+
+ public abstract class PartialResultsWithInitialValue :
+ Base,
+ IJsonRpcRequestHandler
+ where TParams : IPartialItemsWithInitialValueRequest
+ where TResponse : IEnumerable?
+ where TRegistrationOptions : class, new()
+ {
+ private readonly IProgressManager _progressManager;
+ private readonly Func, TResponse> _factory;
+
+ protected PartialResultsWithInitialValue(
+ IProgressManager progressManager, Func, TResponse> factory
+ )
+ {
+ _progressManager = progressManager;
+ _factory = factory;
+ }
+
+ async Task IRequestHandler.Handle(TParams request, CancellationToken cancellationToken)
+ {
+ var observer = _progressManager.For(request, cancellationToken);
+ if (observer != ProgressObserver.Noop)
+ {
+ observer.OnNext(await HandleInitialValue(request, cancellationToken));
+ Handle(request, observer, cancellationToken);
+ await observer;
+ return default;
+ }
+
+ {
+ using var subject = new Subject>();
+ var task = subject
+ .Aggregate(await HandleInitialValue(request, cancellationToken), _factory)
+ .ToTask(cancellationToken, _progressManager.Scheduler)
+ .ConfigureAwait(false);
+ Handle(request, subject, cancellationToken);
+ return await task;
+ }
+ }
+
+ protected abstract Task HandleInitialValue(TParams request, CancellationToken cancellationToken);
+ protected abstract void Handle(TParams request, IObserver> results, CancellationToken cancellationToken);
+ }
+
+ public abstract class PartialResultsWithInitialValueCapability :
+ BaseCapability,
+ IJsonRpcRequestHandler
+ where TParams : IPartialItemsWithInitialValueRequest
+ where TResponse : IEnumerable?
+ where TCapability : ICapability
+ {
+ private readonly IProgressManager _progressManager;
+ private readonly Func, TResponse> _factory;
+
+ protected PartialResultsWithInitialValueCapability(
+ IProgressManager progressManager, Func, TResponse?> factory
+ )
+ {
+ _progressManager = progressManager;
+ _factory = factory;
+ }
+
+ async Task IRequestHandler.Handle(TParams request, CancellationToken cancellationToken)
+ {
+ var observer = _progressManager.For(request, cancellationToken);
+ if (observer != ProgressObserver.Noop)
+ {
+ observer.OnNext(await HandleInitialValue(request, cancellationToken));
+ Handle(request, observer, cancellationToken);
+ await observer;
+ return default;
+ }
+
+ {
+ using var subject = new Subject>();
+ var task = subject
+ .Aggregate(await HandleInitialValue(request, cancellationToken), _factory)
+ .ToTask(cancellationToken, _progressManager.Scheduler)
+ .ConfigureAwait(false);
+ Handle(request, subject, cancellationToken);
+ return await task;
+ }
+ }
+
+ protected abstract Task HandleInitialValue(TParams request, CancellationToken cancellationToken);
+ protected abstract void Handle(TParams request, IObserver> results, CancellationToken cancellationToken);
+ }
+ }
+}
diff --git a/src/Protocol/AbstractHandlers.Request.cs b/src/Protocol/AbstractHandlers.Request.cs
new file mode 100644
index 000000000..475f6f1e8
--- /dev/null
+++ b/src/Protocol/AbstractHandlers.Request.cs
@@ -0,0 +1,55 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reactive.Linq;
+using System.Reactive.Subjects;
+using System.Reactive.Threading.Tasks;
+using System.Threading;
+using System.Threading.Tasks;
+using MediatR;
+using OmniSharp.Extensions.JsonRpc;
+using OmniSharp.Extensions.LanguageServer.Protocol.Client.Capabilities;
+using OmniSharp.Extensions.LanguageServer.Protocol.Models;
+using OmniSharp.Extensions.LanguageServer.Protocol.Progress;
+
+namespace OmniSharp.Extensions.LanguageServer.Protocol
+{
+ public static partial class AbstractHandlers
+ {
+
+ public abstract class Request :
+ IJsonRpcRequestHandler
+ where TParams : IRequest
+ {
+ public abstract Task Handle(TParams request, CancellationToken cancellationToken);
+ }
+
+ public abstract class Request :
+ Base,
+ IJsonRpcRequestHandler
+ where TParams : IRequest
+ where TRegistrationOptions : class, new()
+ {
+ public abstract Task Handle(TParams request, CancellationToken cancellationToken);
+ }
+
+ public abstract class Request :
+ Base,
+ IJsonRpcRequestHandler
+ where TParams : IRequest
+ where TRegistrationOptions : class, new()
+ where TCapability : ICapability
+ {
+ public abstract Task Handle(TParams request, CancellationToken cancellationToken);
+ }
+
+ public abstract class RequestCapability :
+ BaseCapability,
+ IJsonRpcRequestHandler
+ where TParams : IRequest
+ where TCapability : ICapability
+ {
+ public abstract Task Handle(TParams request, CancellationToken cancellationToken);
+ }
+ }
+}
diff --git a/src/Protocol/Client/Capabilities/ClientCapabilities.cs b/src/Protocol/Client/Capabilities/ClientCapabilities.cs
index 07be4f2f9..53884be40 100644
--- a/src/Protocol/Client/Capabilities/ClientCapabilities.cs
+++ b/src/Protocol/Client/Capabilities/ClientCapabilities.cs
@@ -18,6 +18,14 @@ public class ClientCapabilities : CapabilitiesBase, IClientCapabilities
[Optional]
public TextDocumentClientCapabilities? TextDocument { get; set; }
+ ///
+ /// Capabilities specific to the notebook document support.
+ ///
+ /// @since 3.17.0
+ ///
+ [Optional]
+ public NotebookDocumentClientCapabilities? NotebookDocument { get; set; }
+
///
/// Window specific client capabilities.
///
diff --git a/src/Protocol/Client/Capabilities/GeneralClientCapabilities.cs b/src/Protocol/Client/Capabilities/GeneralClientCapabilities.cs
index f7f2ca959..2d1eb66aa 100644
--- a/src/Protocol/Client/Capabilities/GeneralClientCapabilities.cs
+++ b/src/Protocol/Client/Capabilities/GeneralClientCapabilities.cs
@@ -1,4 +1,5 @@
-using OmniSharp.Extensions.LanguageServer.Protocol.Serialization;
+using OmniSharp.Extensions.LanguageServer.Protocol.Models;
+using OmniSharp.Extensions.LanguageServer.Protocol.Serialization;
namespace OmniSharp.Extensions.LanguageServer.Protocol.Client.Capabilities
{
@@ -20,6 +21,41 @@ public class GeneralClientCapabilities : CapabilitiesBase, IGeneralClientCapabil
///
/// @since 3.16.0
///
- [Optional] public MarkdownClientCapabilities? Markdown { get; set; }
+ [Optional]
+ public MarkdownClientCapabilities? Markdown { get; set; }
+
+ ///
+ /// Client capability that signals how the client
+ /// handles stale requests (e.g. a request
+ /// for which the client will not process the response
+ /// anymore since the information is outdated).
+ ///
+ /// @since 3.17.0
+ ///
+ [Optional]
+ public StaleRequestSupportClientCapabilities? StaleRequestSupport { get; set; }
+
+ ///
+ /// The position encodings supported by the client. Client and server
+ /// have to agree on the same position encoding to ensure that offsets
+ /// (e.g. character position in a line) are interpreted the same on both
+ /// side.
+ ///
+ /// To keep the protocol backwards compatible the following applies: if
+ /// the value 'utf-16' is missing from the array of position encodings
+ /// servers can assume that the client supports UTF-16. UTF-16 is
+ /// therefore a mandatory encoding.
+ ///
+ /// If omitted it defaults to ['utf-16'].
+ ///
+ /// Implementation considerations: since the conversion from one encoding
+ /// into another requires the content of the file / line the conversion
+ /// is best done where the file is read which is usually on the server
+ /// side.
+ ///
+ /// @since 3.17.0
+ ///
+ [Optional]
+ public Container? PositionEncodings { get; set; }
}
-}
\ No newline at end of file
+}
diff --git a/src/Protocol/Client/Capabilities/IGeneralClientCapabilities.cs b/src/Protocol/Client/Capabilities/IGeneralClientCapabilities.cs
index 06c15abfe..c036a4cad 100644
--- a/src/Protocol/Client/Capabilities/IGeneralClientCapabilities.cs
+++ b/src/Protocol/Client/Capabilities/IGeneralClientCapabilities.cs
@@ -1,4 +1,6 @@
-namespace OmniSharp.Extensions.LanguageServer.Protocol.Client.Capabilities
+using OmniSharp.Extensions.LanguageServer.Protocol.Models;
+
+namespace OmniSharp.Extensions.LanguageServer.Protocol.Client.Capabilities
{
public interface IGeneralClientCapabilities
{
@@ -15,5 +17,37 @@ public interface IGeneralClientCapabilities
/// @since 3.16.0
///
MarkdownClientCapabilities? Markdown { get; set; }
+
+ ///
+ /// Client capability that signals how the client
+ /// handles stale requests (e.g. a request
+ /// for which the client will not process the response
+ /// anymore since the information is outdated).
+ ///
+ /// @since 3.17.0
+ ///
+ StaleRequestSupportClientCapabilities? StaleRequestSupport { get; set; }
+
+ ///
+ /// The position encodings supported by the client. Client and server
+ /// have to agree on the same position encoding to ensure that offsets
+ /// (e.g. character position in a line) are interpreted the same on both
+ /// side.
+ ///
+ /// To keep the protocol backwards compatible the following applies: if
+ /// the value 'utf-16' is missing from the array of position encodings
+ /// servers can assume that the client supports UTF-16. UTF-16 is
+ /// therefore a mandatory encoding.
+ ///
+ /// If omitted it defaults to ['utf-16'].
+ ///
+ /// Implementation considerations: since the conversion from one encoding
+ /// into another requires the content of the file / line the conversion
+ /// is best done where the file is read which is usually on the server
+ /// side.
+ ///
+ /// @since 3.17.0
+ ///
+ Container? PositionEncodings { get; set; }
}
-}
\ No newline at end of file
+}
diff --git a/src/Protocol/Client/Capabilities/ITextDocumentClientCapabilities.cs b/src/Protocol/Client/Capabilities/ITextDocumentClientCapabilities.cs
index 943dc8e52..fb7104c29 100644
--- a/src/Protocol/Client/Capabilities/ITextDocumentClientCapabilities.cs
+++ b/src/Protocol/Client/Capabilities/ITextDocumentClientCapabilities.cs
@@ -2,7 +2,7 @@
{
public interface ITextDocumentClientCapabilities : ICapabilitiesBase
{
- Supports Synchronization { get; set; }
+ Supports Synchronization { get; set; }
///
/// Capabilities specific to the `textDocument/completion`
@@ -146,5 +146,33 @@ public interface ITextDocumentClientCapabilities : ICapabilitiesBase
/// @since 3.16.0
///
Supports Moniker { get; set; }
+
+ ///
+ /// Capabilities specific to the various type hierarchy requests.
+ ///
+ /// @since 3.17.0
+ ///
+ Supports TypeHierarchy { get; set; }
+
+ ///
+ /// Capabilities specific to the `textDocument/inlineValue` request.
+ ///
+ /// @since 3.17.0
+ ///
+ Supports InlineValue { get; set; }
+
+ ///
+ /// Capability specific to the `textDocument/inlayHint` request.
+ ///
+ /// @since 3.17.0
+ ///
+ Supports InlayHint { get; set; }
+
+ ///
+ /// Capability specific to the diagnostic pull model.
+ ///
+ /// @since 3.17.0
+ ///
+ Supports Diagnostic { get; set; }
}
-}
\ No newline at end of file
+}
diff --git a/src/Protocol/Client/Capabilities/IWindowClientCapabilities.cs b/src/Protocol/Client/Capabilities/IWindowClientCapabilities.cs
index 764287c43..900bff3ea 100644
--- a/src/Protocol/Client/Capabilities/IWindowClientCapabilities.cs
+++ b/src/Protocol/Client/Capabilities/IWindowClientCapabilities.cs
@@ -3,7 +3,7 @@
public interface IWindowClientCapabilities : ICapabilitiesBase
{
///
- /// Whether client supports handling progress notifications.
+ /// Whether the client supports server initiated progress using the `window/workDoneProgress/create` request.
///
Supports WorkDoneProgress { get; set; }
@@ -21,4 +21,4 @@ public interface IWindowClientCapabilities : ICapabilitiesBase
///
Supports ShowDocument { get; set; }
}
-}
\ No newline at end of file
+}
diff --git a/src/Protocol/Client/Capabilities/MarkdownClientCapabilities.cs b/src/Protocol/Client/Capabilities/MarkdownClientCapabilities.cs
index 608e196e1..177d69a1a 100644
--- a/src/Protocol/Client/Capabilities/MarkdownClientCapabilities.cs
+++ b/src/Protocol/Client/Capabilities/MarkdownClientCapabilities.cs
@@ -1,3 +1,4 @@
+using OmniSharp.Extensions.LanguageServer.Protocol.Models;
using OmniSharp.Extensions.LanguageServer.Protocol.Serialization;
namespace OmniSharp.Extensions.LanguageServer.Protocol.Client.Capabilities
@@ -12,12 +13,21 @@ public class MarkdownClientCapabilities
///
/// The name of the parser.
///
- public string Parser { get; set; }
+ public string Parser { get; set; } = null!;
///
/// The version of the parser.
///
[Optional]
public string? Version { get; set; }
+
+ ///
+ /// A list of HTML tags that the client allows / supports in
+ /// Markdown.
+ ///
+ /// @since 3.17.0
+ ///
+ [Optional]
+ public Container? AllowedTags { get; set; }
}
}
diff --git a/src/Protocol/Client/Capabilities/NotebookDocumentClientCapabilities.cs b/src/Protocol/Client/Capabilities/NotebookDocumentClientCapabilities.cs
new file mode 100644
index 000000000..b86d035e2
--- /dev/null
+++ b/src/Protocol/Client/Capabilities/NotebookDocumentClientCapabilities.cs
@@ -0,0 +1,16 @@
+namespace OmniSharp.Extensions.LanguageServer.Protocol.Client.Capabilities;
+
+///
+/// Capabilities specific to the notebook document support.
+///
+/// @since 3.17.0
+///
+public class NotebookDocumentClientCapabilities
+{
+ ///
+ /// Capabilities specific to notebook document synchronization
+ ///
+ /// @since 3.17.0
+ ///
+ public Supports Synchronization { get; set; }
+}
diff --git a/src/Protocol/Client/Capabilities/StaleRequestSupportClientCapabilities.cs b/src/Protocol/Client/Capabilities/StaleRequestSupportClientCapabilities.cs
new file mode 100644
index 000000000..64577a4d2
--- /dev/null
+++ b/src/Protocol/Client/Capabilities/StaleRequestSupportClientCapabilities.cs
@@ -0,0 +1,26 @@
+using OmniSharp.Extensions.LanguageServer.Protocol.Models;
+
+namespace OmniSharp.Extensions.LanguageServer.Protocol.Client.Capabilities;
+
+///
+/// Client capability that signals how the client
+/// handles stale requests (e.g. a request
+/// for which the client will not process the response
+/// anymore since the information is outdated).
+///
+/// @since 3.17.0
+///
+public class StaleRequestSupportClientCapabilities
+{
+ ///
+ /// The client will actively cancel the request.
+ ///
+ public bool Cancel { get; set; }
+
+ ///
+ /// The list of requests for which the client
+ /// will retry the request if it receives a
+ /// response with error code `ContentModified``
+ ///
+ public Container RetryOnContentModified { get; set; } = new();
+}
diff --git a/src/Protocol/Client/Capabilities/SymbolKindCapabilityOptions.cs b/src/Protocol/Client/Capabilities/SymbolKindCapabilityOptions.cs
deleted file mode 100644
index 043c3781c..000000000
--- a/src/Protocol/Client/Capabilities/SymbolKindCapabilityOptions.cs
+++ /dev/null
@@ -1,24 +0,0 @@
-using OmniSharp.Extensions.LanguageServer.Protocol.Models;
-using OmniSharp.Extensions.LanguageServer.Protocol.Serialization;
-
-namespace OmniSharp.Extensions.LanguageServer.Protocol.Client.Capabilities
-{
- ///
- /// Specific capabilities for the `SymbolKind`.
- ///
- public class SymbolKindCapabilityOptions
- {
- ///
- /// The symbol kind values the client supports. When this
- /// property exists the client also guarantees that it will
- /// handle values outside its set gracefully and falls back
- /// to a default value when unknown.
- ///
- /// If this property is not present the client only supports
- /// the symbol kinds from `File` to `Array` as defined in
- /// the initial version of the protocol.
- ///
- [Optional]
- public Container? ValueSet { get; set; }
- }
-}
diff --git a/src/Protocol/Client/Capabilities/TagSupportCapabilityOptions.cs b/src/Protocol/Client/Capabilities/TagSupportCapabilityOptions.cs
deleted file mode 100644
index f0bbaeb7d..000000000
--- a/src/Protocol/Client/Capabilities/TagSupportCapabilityOptions.cs
+++ /dev/null
@@ -1,19 +0,0 @@
-using OmniSharp.Extensions.LanguageServer.Protocol.Models;
-
-namespace OmniSharp.Extensions.LanguageServer.Protocol.Client.Capabilities
-{
- ///
- /// The client supports tags on `SymbolInformation`.Tags are supported on
- /// `DocumentSymbol` if `hierarchicalDocumentSymbolSupport` is set tot true.
- /// Clients supporting tags have to handle unknown tags gracefully.
- ///
- /// @since 3.16.0
- ///
- public class TagSupportCapabilityOptions
- {
- ///
- /// The tags supported by the client.
- ///
- public Container ValueSet { get; set; } = null!;
- }
-}
diff --git a/src/Protocol/Client/Capabilities/TextDocumentClientCapabilities.cs b/src/Protocol/Client/Capabilities/TextDocumentClientCapabilities.cs
index f74b73634..c8b70d5d5 100644
--- a/src/Protocol/Client/Capabilities/TextDocumentClientCapabilities.cs
+++ b/src/Protocol/Client/Capabilities/TextDocumentClientCapabilities.cs
@@ -2,7 +2,7 @@ namespace OmniSharp.Extensions.LanguageServer.Protocol.Client.Capabilities
{
public class TextDocumentClientCapabilities : CapabilitiesBase, ITextDocumentClientCapabilities
{
- public Supports Synchronization { get; set; }
+ public Supports Synchronization { get; set; }
///
/// Capabilities specific to the `textDocument/completion`
@@ -146,5 +146,33 @@ public class TextDocumentClientCapabilities : CapabilitiesBase, ITextDocumentCli
/// @since 3.16.0
///
public Supports Moniker { get; set; }
+
+ ///
+ /// Capabilities specific to the various type hierarchy requests.
+ ///
+ /// @since 3.17.0
+ ///
+ public Supports TypeHierarchy { get; set; }
+
+ ///
+ /// Capabilities specific to the `textDocument/inlineValue` request.
+ ///
+ /// @since 3.17.0
+ ///
+ public Supports InlineValue { get; set; }
+
+ ///
+ /// Capability specific to the `textDocument/inlayHint` request.
+ ///
+ /// @since 3.17.0
+ ///
+ public Supports InlayHint { get; set; }
+
+ ///
+ /// Capability specific to the diagnostic pull model.
+ ///
+ /// @since 3.17.0
+ ///
+ public Supports Diagnostic { get; set; }
}
}
diff --git a/src/Protocol/Client/Capabilities/WindowClientCapabilities.cs b/src/Protocol/Client/Capabilities/WindowClientCapabilities.cs
index 24ba5cebc..ba40b2e0f 100644
--- a/src/Protocol/Client/Capabilities/WindowClientCapabilities.cs
+++ b/src/Protocol/Client/Capabilities/WindowClientCapabilities.cs
@@ -6,7 +6,7 @@ namespace OmniSharp.Extensions.LanguageServer.Protocol.Client.Capabilities
public class WindowClientCapabilities : CapabilitiesBase, IWindowClientCapabilities
{
///
- /// Whether client supports handling progress notifications.
+ /// Whether the client supports server initiated progress using the `window/workDoneProgress/create` request.
///
public Supports WorkDoneProgress { get; set; }
diff --git a/src/Protocol/Client/Capabilities/WorkspaceClientCapabilities.cs b/src/Protocol/Client/Capabilities/WorkspaceClientCapabilities.cs
index 94dd06b5c..0f8d22833 100644
--- a/src/Protocol/Client/Capabilities/WorkspaceClientCapabilities.cs
+++ b/src/Protocol/Client/Capabilities/WorkspaceClientCapabilities.cs
@@ -54,6 +54,27 @@ public class WorkspaceClientCapabilities : CapabilitiesBase
///
public Supports FileOperations { get; set; }
+ ///
+ /// Client workspace capabilities specific to inline values.
+ ///
+ /// @since 3.17.0
+ ///
+ public Supports InlineValue { get; set; }
+
+ ///
+ /// Client workspace capabilities specific to inlay hints.
+ ///
+ /// @since 3.17.0
+ ///
+ public Supports InlayHint { get; set; }
+
+ ///
+ /// Client workspace capabilities specific to diagnostics.
+ ///
+ /// @since 3.17.0.
+ ///
+ public Supports Diagnostics { get; set; }
+
///
/// The client has support for workspace folders.
///
@@ -68,6 +89,4 @@ public class WorkspaceClientCapabilities : CapabilitiesBase
///
public Supports Configuration { get; set; }
}
-
-
}
diff --git a/src/Protocol/Client/ILanguageClientFacade.cs b/src/Protocol/Client/ILanguageClientFacade.cs
index 8b29aaeee..48e6817e4 100644
--- a/src/Protocol/Client/ILanguageClientFacade.cs
+++ b/src/Protocol/Client/ILanguageClientFacade.cs
@@ -5,6 +5,7 @@ namespace OmniSharp.Extensions.LanguageServer.Protocol.Client
public interface ILanguageClientFacade : ILanguageClientProxy, IJsonRpcHandlerInstance
{
ITextDocumentLanguageClient TextDocument { get; }
+ INotebookDocumentLanguageClient NotebookDocument { get; }
IClientLanguageClient Client { get; }
IGeneralLanguageClient General { get; }
IWindowLanguageClient Window { get; }
diff --git a/src/Protocol/Client/INotebookDocumentLanguageClient.cs b/src/Protocol/Client/INotebookDocumentLanguageClient.cs
new file mode 100644
index 000000000..f1be3c184
--- /dev/null
+++ b/src/Protocol/Client/INotebookDocumentLanguageClient.cs
@@ -0,0 +1,5 @@
+namespace OmniSharp.Extensions.LanguageServer.Protocol.Client;
+
+public interface INotebookDocumentLanguageClient : ILanguageClientProxy
+{
+}
diff --git a/src/Protocol/Client/NotebookDocumentLanguageClient.cs b/src/Protocol/Client/NotebookDocumentLanguageClient.cs
new file mode 100644
index 000000000..8c2202c9c
--- /dev/null
+++ b/src/Protocol/Client/NotebookDocumentLanguageClient.cs
@@ -0,0 +1,15 @@
+using DryIoc;
+using OmniSharp.Extensions.JsonRpc;
+using OmniSharp.Extensions.LanguageServer.Protocol.Progress;
+
+namespace OmniSharp.Extensions.LanguageServer.Protocol.Client;
+
+internal class NotebookDocumentLanguageClient : LanguageProtocolProxy, INotebookDocumentLanguageClient
+{
+ public NotebookDocumentLanguageClient(
+ IResponseRouter requestRouter, IResolverContext resolverContext, IProgressManager progressManager,
+ ILanguageProtocolSettings languageProtocolSettings
+ ) : base(requestRouter, resolverContext, progressManager, languageProtocolSettings)
+ {
+ }
+}
diff --git a/src/Protocol/Client/WorkDone/WorkDoneProxyExtensions.cs b/src/Protocol/Client/WorkDone/WorkDoneProxyExtensions.cs
index 53b97c59f..6312c00d9 100644
--- a/src/Protocol/Client/WorkDone/WorkDoneProxyExtensions.cs
+++ b/src/Protocol/Client/WorkDone/WorkDoneProxyExtensions.cs
@@ -60,6 +60,24 @@ public static TResult ObserveWorkDone(
DoObserveWorkDone(proxy, @params, observer);
return func(proxy, @params);
}
+
+ public static TResult ObserveWorkDone(
+ this INotebookDocumentLanguageClient proxy, T @params, Func func, IObserver observer
+ )
+ where T : IWorkDoneProgressParams
+ {
+ DoObserveWorkDone(proxy, @params, observer);
+ return func(proxy, @params);
+ }
+
+ public static TResult ObserveWorkDone(
+ this INotebookDocumentLanguageClient proxy, T @params, Func func, IWorkDoneProgressObserver observer
+ )
+ where T : IWorkDoneProgressParams
+ {
+ DoObserveWorkDone(proxy, @params, observer);
+ return func(proxy, @params);
+ }
public static TResult ObserveWorkDone(
this IWindowLanguageClient proxy, T @params, Func func, IObserver observer
diff --git a/src/Protocol/Document/INotebookDocumentIdentifier.cs b/src/Protocol/Document/INotebookDocumentIdentifier.cs
new file mode 100644
index 000000000..082ce481e
--- /dev/null
+++ b/src/Protocol/Document/INotebookDocumentIdentifier.cs
@@ -0,0 +1,50 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Reactive.Disposables;
+
+// ReSharper disable once CheckNamespace
+namespace OmniSharp.Extensions.LanguageServer.Protocol.Document
+{
+ public interface INotebookDocumentIdentifier
+ {
+ ///
+ /// Returns the attributes for the document at the given URI. This can return null.
+ ///
+ ///
+ ///
+ NotebookDocumentAttributes GetNotebookDocumentAttributes(DocumentUri uri);
+ }
+
+ public abstract class NotebookDocumentIdentifierBase : INotebookDocumentIdentifier
+ {
+ public NotebookDocumentAttributes GetNotebookDocumentAttributes(DocumentUri uri)
+ {
+ var (languageId, schema) = GetAttributes(uri);
+ return new NotebookDocumentAttributes(uri, languageId, schema);
+ }
+
+ protected abstract (string notebookType, string schema) GetAttributes(DocumentUri uri);
+ }
+
+ public class NotebookDocumentIdentifiers : IEnumerable
+ {
+ private readonly HashSet _NotebookDocumentIdentifiers = new HashSet();
+ public IEnumerator GetEnumerator() => _NotebookDocumentIdentifiers.GetEnumerator();
+ IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
+
+ public IDisposable Add(params INotebookDocumentIdentifier[] identifiers)
+ {
+ foreach (var item in identifiers)
+ _NotebookDocumentIdentifiers.Add(item);
+ return Disposable.Create(
+ () => {
+ foreach (var NotebookDocumentIdentifier in identifiers)
+ {
+ _NotebookDocumentIdentifiers.Remove(NotebookDocumentIdentifier);
+ }
+ }
+ );
+ }
+ }
+}
diff --git a/src/Protocol/Document/NotebookDocumentAttributes.cs b/src/Protocol/Document/NotebookDocumentAttributes.cs
new file mode 100644
index 000000000..b7f39c32c
--- /dev/null
+++ b/src/Protocol/Document/NotebookDocumentAttributes.cs
@@ -0,0 +1,69 @@
+namespace OmniSharp.Extensions.LanguageServer.Protocol.Document;
+
+public class NotebookDocumentAttributes : IEquatable
+{
+ public NotebookDocumentAttributes(DocumentUri uri, string notebookType)
+ {
+ Uri = uri;
+ NotebookType = notebookType;
+ }
+
+ public NotebookDocumentAttributes(DocumentUri uri)
+ {
+ Uri = uri;
+ }
+
+ public NotebookDocumentAttributes(string language)
+ {
+ Language = language;
+ }
+
+ public NotebookDocumentAttributes(string language, DocumentUri uri)
+ {
+ Language = language;
+ Uri = uri;
+ }
+
+ public NotebookDocumentAttributes(DocumentUri uri, string scheme, string notebookType)
+ {
+ Uri = uri;
+ Scheme = scheme;
+ NotebookType = notebookType;
+ }
+
+ public DocumentUri Uri { get; }
+ public string? Scheme { get; }
+ public string? NotebookType { get; }
+ public string? Language { get; }
+
+ public bool Equals(NotebookDocumentAttributes? other)
+ {
+ if (ReferenceEquals(null, other)) return false;
+ if (ReferenceEquals(this, other)) return true;
+ return Uri.Equals(other.Uri) && Scheme == other.Scheme && NotebookType == other.NotebookType;
+ }
+
+ public override bool Equals(object? obj)
+ {
+ if (ReferenceEquals(null, obj)) return false;
+ if (ReferenceEquals(this, obj)) return true;
+ if (obj.GetType() != GetType()) return false;
+ return Equals((NotebookDocumentAttributes) obj);
+ }
+
+ public override int GetHashCode()
+ {
+ unchecked
+ {
+ var hashCode = Uri.GetHashCode();
+ hashCode = ( hashCode * 397 ) ^ ( Scheme != null ? Scheme.GetHashCode() : 0 );
+ hashCode = ( hashCode * 397 ) ^ ( NotebookType != null ? NotebookType.GetHashCode() : 0 );
+ hashCode = ( hashCode * 397 ) ^ ( Language != null ? Language.GetHashCode() : 0 );
+ return hashCode;
+ }
+ }
+
+ public static bool operator ==(NotebookDocumentAttributes? left, NotebookDocumentAttributes? right) => Equals(left, right);
+
+ public static bool operator !=(NotebookDocumentAttributes? left, NotebookDocumentAttributes? right) => !Equals(left, right);
+}
diff --git a/src/Protocol/Features/Document/CallHierarchyFeature.cs b/src/Protocol/Features/Document/CallHierarchyFeature.cs
index 73f0949dd..6e49ee177 100644
--- a/src/Protocol/Features/Document/CallHierarchyFeature.cs
+++ b/src/Protocol/Features/Document/CallHierarchyFeature.cs
@@ -112,8 +112,8 @@ public abstract record CallHierarchyBaseCallParams : ICanBeResolved
JToken? ICanBeResolved.Data
{
- get => Item.GetRawData();
- init => Item.SetRawData(value);
+ get => Item?.GetRawData();
+ init => Item?.SetRawData(value);
}
}
@@ -124,8 +124,8 @@ public abstract record CallHierarchyBaseCallParams : ICanBeResolved
JToken? ICanBeResolved.Data
{
- get => Item.GetRawData();
- init => Item.SetRawData(value);
+ get => Item?.GetRawData();
+ init => Item?.SetRawData(value);
}
}
diff --git a/src/Protocol/Features/Document/CodeActionFeature.cs b/src/Protocol/Features/Document/CodeActionFeature.cs
index 19bf652b9..36ca7aac9 100644
--- a/src/Protocol/Features/Document/CodeActionFeature.cs
+++ b/src/Protocol/Features/Document/CodeActionFeature.cs
@@ -30,7 +30,7 @@ namespace Models
[RegistrationOptions(typeof(CodeActionRegistrationOptions))]
[Capability(typeof(CodeActionCapability))]
[Resolver(typeof(CodeAction))]
- public partial record CodeActionParams : ITextDocumentIdentifierParams, IPartialItemsRequest,
+ public partial record CodeActionParams : ITextDocumentIdentifierParams, IPartialItemsRequest,
IWorkDoneProgressParams
{
///
@@ -49,6 +49,9 @@ public partial record CodeActionParams : ITextDocumentIdentifierParams, IPartial
public CodeActionContext Context { get; init; } = null!;
}
+ // marker class is required
+ public partial class CommandOrCodeActionContainer {}
+
///
/// Contains additional diagnostic information about the context in which
/// a code action is run.
@@ -72,6 +75,14 @@ public record CodeActionContext
///
[Optional]
public Container? Only { get; init; }
+
+ ///
+ /// The reason why code actions were requested.
+ ///
+ /// @since 3.17.0
+ ///
+ [Optional]
+ public CodeActionTriggerKind? TriggerKind { get; init; }
}
[DebuggerDisplay("{" + nameof(DebuggerDisplay) + ",nq}")]
@@ -414,6 +425,35 @@ public readonly partial struct CodeActionKind
/// Base kind for an organize imports source action: `source.organizeImports`
///
public static CodeActionKind SourceOrganizeImports { get; } = new CodeActionKind("source.organizeImports");
+
+ ///
+ /// Base kind for a 'fix all' source action: `source.fixAll`.
+ ///
+ /// 'Fix all' actions automatically fix errors that have a clear fix that
+ /// do not require user input. They should not suppress errors or perform
+ /// unsafe fixes such as generating new types or classes.
+ ///
+ /// @since 3.17.0
+ ///
+ public static CodeActionKind SourceFixAll { get; } = new CodeActionKind("source.fixAll");
+ }
+
+
+ [JsonConverter(typeof(NumberEnumConverter))]
+ public enum CodeActionTriggerKind
+ {
+ ///
+ /// Code actions were explicitly requested by the user or by an extension.
+ ///
+ Invoked = 1,
+
+ ///
+ /// Code actions were requested automatically.
+ ///
+ /// This typically happens when current selection in a file changes, but can
+ /// also be triggered when file content changes.
+ ///
+ Automatic = 2
}
}
diff --git a/src/Protocol/Features/Document/CodeLensFeature.cs b/src/Protocol/Features/Document/CodeLensFeature.cs
index 66d7ea1d5..fa9af0f21 100644
--- a/src/Protocol/Features/Document/CodeLensFeature.cs
+++ b/src/Protocol/Features/Document/CodeLensFeature.cs
@@ -25,7 +25,7 @@ namespace Models
[RegistrationOptions(typeof(CodeLensRegistrationOptions))]
[Capability(typeof(CodeLensCapability))]
[Resolver(typeof(CodeLens))]
- public partial record CodeLensParams : ITextDocumentIdentifierParams, IWorkDoneProgressParams, IPartialItemsRequest
+ public partial record CodeLensParams : ITextDocumentIdentifierParams, IWorkDoneProgressParams, IPartialItemsRequest
{
///
/// The document to request code lens for.
@@ -33,6 +33,9 @@ public partial record CodeLensParams : ITextDocumentIdentifierParams, IWorkDoneP
public TextDocumentIdentifier TextDocument { get; init; } = null!;
}
+ // marker class is required
+ public partial class CodeLensContainer {}
+
///
/// A code lens represents a command that should be shown along with
/// source text, like the number of references, a way to run tests, etc.
@@ -108,10 +111,7 @@ public override StaticOptions Convert(CodeLensRegistrationOptions source)
}
}
}
- }
-
- namespace Models
- {
+
[Parallel]
[Method(WorkspaceNames.CodeLensRefresh, Direction.ServerToClient)]
[GenerateHandler("OmniSharp.Extensions.LanguageServer.Protocol.Workspace")]
diff --git a/src/Protocol/Features/Document/ColorFeature.cs b/src/Protocol/Features/Document/ColorFeature.cs
index ee8d60b24..457691592 100644
--- a/src/Protocol/Features/Document/ColorFeature.cs
+++ b/src/Protocol/Features/Document/ColorFeature.cs
@@ -20,7 +20,7 @@ namespace Models
[GenerateRequestMethods(typeof(ITextDocumentLanguageClient), typeof(ILanguageClient))]
[RegistrationOptions(typeof(DocumentColorRegistrationOptions))]
[Capability(typeof(ColorProviderCapability))]
- public partial record DocumentColorParams : IPartialItemsRequest, ColorInformation>, IWorkDoneProgressParams
+ public partial record DocumentColorParams : IPartialItemsRequest?, ColorInformation>, IWorkDoneProgressParams
{
///
/// The text document.
@@ -76,7 +76,7 @@ public partial record ColorPresentation
///
/// An [edit](#TextEdit) which is applied to a document when selecting
- /// this presentation for the color. When `falsy` the [label](#ColorPresentation.label)
+ /// this presentation for the color. When omitted the [label](#ColorPresentation.label)
/// is used.
///
[Optional]
diff --git a/src/Protocol/Features/Document/CompletionFeature.cs b/src/Protocol/Features/Document/CompletionFeature.cs
index 0f13e8824..d3e2a8246 100644
--- a/src/Protocol/Features/Document/CompletionFeature.cs
+++ b/src/Protocol/Features/Document/CompletionFeature.cs
@@ -1,6 +1,7 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
+using System.Reflection;
using MediatR;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
@@ -28,7 +29,7 @@ namespace Models
GenerateRequestMethods(typeof(ITextDocumentLanguageClient), typeof(ILanguageClient))
]
[RegistrationOptions(typeof(CompletionRegistrationOptions)), Capability(typeof(CompletionCapability)), Resolver(typeof(CompletionItem))]
- public partial record CompletionParams : TextDocumentPositionParams, IWorkDoneProgressParams, IPartialItemsRequest
+ public partial record CompletionParams : TextDocumentPositionParams, IWorkDoneProgressParams, IPartialItemsWithInitialValueRequest
{
///
/// The completion context. This is only available it the client specifies to send
@@ -45,7 +46,7 @@ public partial record CompletionParams : TextDocumentPositionParams, IWorkDonePr
GenerateHandler("OmniSharp.Extensions.LanguageServer.Protocol.Document", Name = "CompletionResolve"),
GenerateHandlerMethods,
GenerateRequestMethods(typeof(ITextDocumentLanguageClient), typeof(ILanguageClient)),
- GenerateContainer("CompletionList"),
+ GenerateContainer("CompletionList", GenerateImplicitConversion = false),
GenerateTypedData
]
[Capability(typeof(CompletionCapability))]
@@ -58,6 +59,14 @@ public partial record CompletionItem : ICanBeResolved, IRequest,
///
public string Label { get; init; }
+ ///
+ /// Additional details for the label
+ ///
+ /// @since 3.17.0 - proposed state
+ ///
+ [Optional]
+ public CompletionItemLabelDetails? LabelDetails { get; init; }
+
///
/// The kind of this completion item. Based of the kind
/// an icon is chosen by the editor.
@@ -104,14 +113,14 @@ public partial record CompletionItem : ICanBeResolved, IRequest,
///
/// A string that shoud be used when comparing this item
- /// with other items. When `falsy` the label is used.
+ /// with other items. When omitted the label is used.
///
[Optional]
public string? SortText { get; init; }
///
/// A string that should be used when filtering a set of
- /// completion items. When `falsy` the label is used.
+ /// completion items. When omitted the label is used.
///
[Optional]
@@ -119,7 +128,7 @@ public partial record CompletionItem : ICanBeResolved, IRequest,
///
/// A string that should be inserted a document when selecting
- /// this completion. When `falsy` the label is used.
+ /// this completion. When omitted the label is used.
///
[Optional]
@@ -168,6 +177,21 @@ public partial record CompletionItem : ICanBeResolved, IRequest,
[Optional]
public TextEditOrInsertReplaceEdit? TextEdit { get; init; }
+ ///
+ /// The edit text used if the completion item is part of a CompletionList and
+ /// CompletionList defines an item default for the text edit range.
+ ///
+ /// Clients will only honor this property if they opt into completion list
+ /// item defaults using the capability `completionList.itemDefaults`.
+ ///
+ /// If not provided and a list's default range is provided the label
+ /// property is used as a text.
+ ///
+ /// @since 3.17.0
+ ///
+ [Optional]
+ public string? TextEditText { get; init; }
+
///
/// An optional array of additional text edits that are applied when
/// selecting this completion. Edits must not overlap with the main edit
@@ -199,7 +223,7 @@ public partial record CompletionItem : ICanBeResolved, IRequest,
[Optional]
public JToken? Data { get; init; }
- private string DebuggerDisplay => $"[{Kind}] {Label}{( Tags?.Any() == true ? $" tags: {string.Join(", ", Tags.Select(z => z.ToString()))}" : "" )}";
+ private string DebuggerDisplay => $"[{Kind}] {Label}{(Tags?.Any() == true ? $" tags: {string.Join(", ", Tags.Select(z => z.ToString()))}" : "")}";
///
public override string ToString() => DebuggerDisplay;
@@ -288,6 +312,15 @@ public partial class CompletionRegistrationOptions : IWorkDoneProgressOptions, I
[Optional]
public Container? AllCommitCharacters { get; set; }
+ ///
+ /// The server supports the following `CompletionItem` specific
+ /// capabilities.
+ ///
+ /// @since 3.17.0 - proposed state
+ ///
+ [Optional]
+ public CompletionRegistrationCompletionItemOptions? CompletionItem { get; set; }
+
class CompletionRegistrationOptionsConverter : RegistrationOptionsConverterBase
{
private readonly IHandlersManager _handlersManager;
@@ -299,16 +332,31 @@ public CompletionRegistrationOptionsConverter(IHandlersManager handlersManager)
public override StaticOptions Convert(CompletionRegistrationOptions source)
{
- return new() {
+ return new()
+ {
ResolveProvider = source.ResolveProvider || _handlersManager.Descriptors.Any(z => z.HandlerType == typeof(ICompletionResolveHandler)),
AllCommitCharacters = source.AllCommitCharacters,
TriggerCharacters = source.TriggerCharacters,
WorkDoneProgress = source.WorkDoneProgress,
+ CompletionItem = source.CompletionItem
};
}
}
}
+ public class CompletionRegistrationCompletionItemOptions
+ {
+ ///