diff --git a/.build/.build.csproj b/.build/.build.csproj
index b3e4dba53..7233e8972 100644
--- a/.build/.build.csproj
+++ b/.build/.build.csproj
@@ -2,11 +2,12 @@
Exe
- net5.0
+ net6.0
false
False
CS0649;CS0169
+ 1
diff --git a/.build/Build.cs b/.build/Build.cs
index 836d1713f..f98da474f 100644
--- a/.build/Build.cs
+++ b/.build/Build.cs
@@ -28,8 +28,7 @@ public partial class Solution : NukeBuild,
IGenerateCodeCoverageReport,
IGenerateCodeCoverageSummary,
IGenerateCodeCoverageBadges,
- IHaveConfiguration,
- ICanLint
+ IHaveConfiguration
{
///
/// Support plugins are available for:
diff --git a/.build/Solution.cs b/.build/Solution.cs
index 47f084d9a..5b98afc89 100644
--- a/.build/Solution.cs
+++ b/.build/Solution.cs
@@ -11,11 +11,11 @@
InvokeTargets = new[] { nameof(Default) },
NonEntryTargets = new[] {
nameof(ICIEnvironment.CIEnvironment),
- nameof(ITriggerCodeCoverageReports.Trigger_Code_Coverage_Reports),
- nameof(ITriggerCodeCoverageReports.Generate_Code_Coverage_Report_Cobertura),
- nameof(IGenerateCodeCoverageBadges.Generate_Code_Coverage_Badges),
- nameof(IGenerateCodeCoverageReport.Generate_Code_Coverage_Report),
- nameof(IGenerateCodeCoverageSummary.Generate_Code_Coverage_Summary),
+ nameof(ITriggerCodeCoverageReports.TriggerCodeCoverageReports),
+ nameof(ITriggerCodeCoverageReports.GenerateCodeCoverageReportCobertura),
+ nameof(IGenerateCodeCoverageBadges.GenerateCodeCoverageBadges),
+ nameof(IGenerateCodeCoverageReport.GenerateCodeCoverageReport),
+ nameof(IGenerateCodeCoverageSummary.GenerateCodeCoverageSummary),
nameof(Default)
},
ExcludedTargets = new[]
@@ -26,20 +26,24 @@
}
)]
[GitHubActionsSteps(
- "ci", GitHubActionsImage.MacOsLatest, GitHubActionsImage.WindowsLatest, GitHubActionsImage.UbuntuLatest,
+ "ci",
+ GitHubActionsImage.MacOsLatest,
+ GitHubActionsImage.WindowsLatest,
+ GitHubActionsImage.UbuntuLatest,
AutoGenerate = false,
On = new[] { GitHubActionsTrigger.Push },
OnPushTags = new[] { "v*" },
- OnPushBranches = new[] { "master", "next" },
- OnPullRequestBranches = new[] { "master", "next" },
+ OnPushBranches = new[] { "master", "main", "next" },
+ OnPullRequestBranches = new[] { "master", "main", "next" },
InvokedTargets = new[] { nameof(Default) },
- NonEntryTargets = new[] {
+ NonEntryTargets = new[]
+ {
nameof(ICIEnvironment.CIEnvironment),
- nameof(ITriggerCodeCoverageReports.Trigger_Code_Coverage_Reports),
- nameof(ITriggerCodeCoverageReports.Generate_Code_Coverage_Report_Cobertura),
- nameof(IGenerateCodeCoverageBadges.Generate_Code_Coverage_Badges),
- nameof(IGenerateCodeCoverageReport.Generate_Code_Coverage_Report),
- nameof(IGenerateCodeCoverageSummary.Generate_Code_Coverage_Summary),
+ nameof(ITriggerCodeCoverageReports.TriggerCodeCoverageReports),
+ nameof(ITriggerCodeCoverageReports.GenerateCodeCoverageReportCobertura),
+ nameof(IGenerateCodeCoverageBadges.GenerateCodeCoverageBadges),
+ nameof(IGenerateCodeCoverageReport.GenerateCodeCoverageReport),
+ nameof(IGenerateCodeCoverageSummary.GenerateCodeCoverageSummary),
nameof(Default)
},
ExcludedTargets = new[] { nameof(ICanClean.Clean), nameof(ICanRestoreWithDotNetCore.DotnetToolRestore) },
@@ -48,27 +52,40 @@
[PrintBuildVersion]
[PrintCIEnvironment]
[UploadLogs]
+[TitleEvents]
public partial class Solution
{
public static RocketSurgeonGitHubActionsConfiguration Middleware(RocketSurgeonGitHubActionsConfiguration configuration)
{
- var buildJob = configuration.Jobs.First(z => z.Name == "Build");
+ var buildJob = configuration.Jobs.OfType().First(z => z.Name == "Build");
+ buildJob.FailFast = false;
var checkoutStep = buildJob.Steps.OfType().Single();
// For fetch all
checkoutStep.FetchDepth = 0;
+ buildJob.Environment["NUGET_PACKAGES"] = "${{ github.workspace }}/.nuget/packages";
buildJob.Steps.InsertRange(
buildJob.Steps.IndexOf(checkoutStep) + 1, new BaseGitHubActionsStep[] {
new RunStep("Fetch all history for all tags and branches") {
Run = "git fetch --prune"
},
- new SetupDotNetStep("Use .NET Core 2.1 SDK") {
- DotNetVersion = "2.1.x"
+ new UsingStep("NuGet Cache")
+ {
+ Uses = "actions/cache@v2",
+ With =
+ {
+ ["path"] = "${{ github.workspace }}/.nuget/packages",
+ // keep in mind using central package versioning here
+ ["key"] =
+ "${{ runner.os }}-nuget-${{ hashFiles('**/Directory.Build.targets', '**/Directory.Build.props', '**/*.csproj') }}",
+ ["restore-keys"] = @"|
+ ${{ runner.os }}-nuget-"
+ }
},
new SetupDotNetStep("Use .NET Core 3.1 SDK") {
DotNetVersion = "3.1.x"
},
- new SetupDotNetStep("Use .NET Core 5.0 SDK") {
- DotNetVersion = "5.0.x"
+ new SetupDotNetStep("Use .NET Core 6.0 SDK") {
+ DotNetVersion = "6.0.x"
},
}
);
@@ -115,24 +132,6 @@ public static RocketSurgeonGitHubActionsConfiguration Middleware(RocketSurgeonGi
}
);
-
- /*
-
- - publish: "${{ parameters.Artifacts }}/logs/"
- displayName: Publish Logs
- artifact: "Logs${{ parameters.Postfix }}"
- condition: always()
-
- - publish: ${{ parameters.Coverage }}
- displayName: Publish Coverage
- artifact: "Coverage${{ parameters.Postfix }}"
- condition: always()
-
- - publish: "${{ parameters.Artifacts }}/nuget/"
- displayName: Publish NuGet Artifacts
- artifact: "NuGet${{ parameters.Postfix }}"
- condition: always()
- */
return configuration;
}
}
diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json
index 19029998d..74333ac0c 100644
--- a/.config/dotnet-tools.json
+++ b/.config/dotnet-tools.json
@@ -1,48 +1,54 @@
{
- "version": 1,
- "isRoot": true,
- "tools": {
- "cake.tool": {
- "version": "1.1.0",
- "commands": [
- "dotnet-cake"
- ]
- },
- "gitversion.tool": {
- "version": "5.7.0",
- "commands": [
- "dotnet-gitversion"
- ]
- },
- "dotnet-reportgenerator-globaltool": {
- "version": "4.8.12",
- "commands": [
- "reportgenerator"
- ]
- },
- "codecov.tool": {
- "version": "1.13.0",
- "commands": [
- "codecov"
- ]
- },
- "nuke.globaltool": {
- "version": "5.3.0",
- "commands": [
- "nuke"
- ]
- },
- "nukeeper": {
- "version": "0.34.0",
- "commands": [
- "nukeeper"
- ]
- },
- "jetbrains.resharper.globaltools": {
- "version": "2021.2.1",
- "commands": [
- "jb"
- ]
+ "version": 1,
+ "isRoot": true,
+ "tools": {
+ "dotnet-outdated": {
+ "version": "2.11.0",
+ "commands": [
+ "dotnet-outdated"
+ ]
+ },
+ "gitversion.tool": {
+ "version": "5.8.2",
+ "commands": [
+ "dotnet-gitversion"
+ ]
+ },
+ "dotnet-reportgenerator-globaltool": {
+ "version": "5.0.4",
+ "commands": [
+ "reportgenerator"
+ ]
+ },
+ "nuke.globaltool": {
+ "version": "6.0.1",
+ "commands": [
+ "nuke"
+ ]
+ },
+ "codecov.tool": {
+ "version": "1.13.0",
+ "commands": [
+ "codecov"
+ ]
+ },
+ "jetbrains.resharper.globaltools": {
+ "version": "2021.3.3",
+ "commands": [
+ "jb"
+ ]
+ },
+ "dotnet-format": {
+ "version": "5.1.250801",
+ "commands": [
+ "dotnet-format"
+ ]
+ },
+ "nukeeper": {
+ "version": "0.35.0",
+ "commands": [
+ "nukeeper"
+ ]
+ }
}
- }
-}
\ No newline at end of file
+}
diff --git a/.editorconfig b/.editorconfig
index 81d812533..737469427 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -1,132 +1,1013 @@
-root=true
+root = true
+
+[*.{cs, cshtml}]
+charset = utf-8
+indent_style = space
+indent_size = 4
+max_line_length = 160
+insert_final_newline = true
+
+[*.{js, ts, vue}]
+indent_style = space
+indent_size = 4
+insert_final_newline = true
+max_line_length = 160
+
+[*.{json, xml, yml, yaml}]
+indent_style = space
+indent_size = 2
+insert_final_newline = true
+max_line_length = 160
+
[*]
-charset=utf-8
-indent_style=space
-indent_size=4
-trim_trailing_whitespace=true
-insert_final_newline=true
-max_line_length=180
-end_of_line=crlf
+#### .NET Coding Conventions ####
-# Microsoft .NET properties
-csharp_new_line_before_members_in_object_initializers=false
-csharp_new_line_before_open_brace=types,methods,properties,indexers,events,event_accessors,control_blocks,anonymous_types,object_collections,array_initializers,local_functions
-csharp_preferred_modifier_order=public, private, protected, internal, new, abstract, virtual, sealed, override, static, readonly, extern, unsafe, volatile, async:suggestion
-csharp_space_between_parentheses=expressions
-csharp_style_expression_bodied_accessors=true:suggestion
-csharp_style_expression_bodied_constructors=true:none
-csharp_style_expression_bodied_indexers=true:none
-csharp_style_expression_bodied_methods=true:none
-csharp_style_expression_bodied_operators=true:none
-csharp_style_expression_bodied_properties=true:suggestion
-csharp_style_var_elsewhere=true:warning
-csharp_style_var_for_built_in_types=true:warning
-csharp_style_var_when_type_is_apparent=true:warning
-dotnet_style_parentheses_in_arithmetic_binary_operators=never_if_unnecessary:warning
-dotnet_style_parentheses_in_other_binary_operators=never_if_unnecessary:warning
-dotnet_style_parentheses_in_relational_binary_operators=never_if_unnecessary:warning
-dotnet_style_predefined_type_for_locals_parameters_members=true:error
-dotnet_style_predefined_type_for_member_access=true:error
-dotnet_style_qualification_for_event=false:warning
-dotnet_style_qualification_for_field=false:warning
-dotnet_style_qualification_for_method=false:warning
-dotnet_style_qualification_for_property=false:warning
-dotnet_style_require_accessibility_modifiers=for_non_interface_members:suggestion
-# Sort using and Import directives with System.* appearing first
-dotnet_sort_system_directives_first=true
-# Suggest more modern language features when available
-dotnet_style_coalesce_expression=true:error
-dotnet_style_collection_initializer=true:suggestion
-dotnet_style_explicit_tuple_names=true:error
-dotnet_style_null_propagation=true:warning
-dotnet_style_object_initializer=true:warning
-
-# Naming Conventions:
-# Pascal Casing
-#dotnet_naming_symbols.method_and_property_symbols.applicable_kinds= method,property,enum
-#dotnet_naming_symbols.method_and_property_symbols.applicable_accessibilities = *
-#dotnet_naming_style.pascal_case_style.capitalization = pascal_case
-csharp_style_conditional_delegate_call=true:suggestion
-csharp_style_inlined_variable_declaration=true:error
-csharp_style_pattern_matching_over_as_with_null_check=true:error
-csharp_style_pattern_matching_over_is_with_cast_check=true:error
-csharp_style_throw_expression=true:suggestion
-csharp_new_line_before_catch=true
-csharp_new_line_before_else=true
-csharp_new_line_before_finally=true
-csharp_new_line_before_members_in_anonymous_types=true
+# Organize usings
+dotnet_separate_import_directive_groups = false
+dotnet_sort_system_directives_first = true
+
+# this. and Me. preferences
+dotnet_style_qualification_for_event = false:warning
+dotnet_style_qualification_for_field = false:warning
+dotnet_style_qualification_for_method = false:warning
+dotnet_style_qualification_for_property = false:warning
+
+# Language keywords vs BCL types preferences
+dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion
+dotnet_style_predefined_type_for_member_access = true:suggestion
+
+# Parentheses preferences
+dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:warning
+dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:warning
+dotnet_style_parentheses_in_other_operators = never_if_unnecessary:warning
+dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:warning
+
+# Modifier preferences
+dotnet_style_require_accessibility_modifiers = for_non_interface_members:suggestion
+
+# Expression-level preferences
+csharp_style_deconstructed_variable_declaration = true:warning
+csharp_style_inlined_variable_declaration = true:warning
+csharp_style_throw_expression = true:warning
+dotnet_style_coalesce_expression = true:warning
+dotnet_style_collection_initializer = true:warning
+dotnet_style_explicit_tuple_names = true:warning
+dotnet_style_null_propagation = true:warning
+dotnet_style_object_initializer = true:warning
+dotnet_style_prefer_auto_properties = true:suggestion
+dotnet_style_prefer_compound_assignment = true:suggestion
+dotnet_style_prefer_conditional_expression_over_assignment = true:suggestion
+dotnet_style_prefer_conditional_expression_over_return = true:suggestion
+dotnet_style_prefer_inferred_anonymous_type_member_names = true:warning
+dotnet_style_prefer_inferred_tuple_names = true:warning
+dotnet_style_prefer_is_null_check_over_reference_equality_method = true:warning
+
+# Field preferences
+dotnet_style_readonly_field = true:warning
+
+# Parameter preferences
+dotnet_code_quality_unused_parameters = non_public:suggestion
+
+#### C# Coding Conventions ####
+
+# var preferences
+csharp_style_var_elsewhere = true:suggestion
+csharp_style_var_for_built_in_types = true:suggestion
+csharp_style_var_when_type_is_apparent = true:suggestion
+
+# Expression-bodied members
+csharp_style_expression_bodied_accessors = true:suggestion
+csharp_style_expression_bodied_constructors = true:suggestion
+csharp_style_expression_bodied_indexers = true:suggestion
+csharp_style_expression_bodied_lambdas = true:suggestion
+csharp_style_expression_bodied_local_functions = true:suggestion
+csharp_style_expression_bodied_methods = true:suggestion
+csharp_style_expression_bodied_operators = true:suggestion
+csharp_style_expression_bodied_properties = true:suggestion
+
+# Pattern matching preferences
+csharp_style_pattern_matching_over_as_with_null_check = true:warning
+csharp_style_pattern_matching_over_is_with_cast_check = true:warning
+csharp_style_prefer_switch_expression = true:warning
+
+# Null-checking preferences
+csharp_style_conditional_delegate_call = true:warning
+
+# Modifier preferences
+csharp_prefer_static_local_function = true:warning
+csharp_preferred_modifier_order = public, private, protected, internal, new, abstract, virtual, sealed, static, readonly, override, extern, unsafe, volatile, async:suggestion
+
+# Code-block preferences
+csharp_prefer_braces = true:none
+csharp_prefer_simple_using_statement = true:suggestion
+
+# Expression-level preferences
+csharp_prefer_simple_default_expression = true:warning
+csharp_style_pattern_local_over_anonymous_function = true:warning
+csharp_style_prefer_index_operator = true:warning
+csharp_style_prefer_range_operator = true:warning
+csharp_style_unused_value_assignment_preference = discard_variable:suggestion
+csharp_style_unused_value_expression_statement_preference = discard_variable:suggestion
+
+# 'using' directive preferences
+
+#### C# Formatting Rules ####
+
+# New line preferences
+csharp_new_line_before_catch = true
+csharp_new_line_before_else = true
+csharp_new_line_before_finally = true
+csharp_new_line_before_members_in_anonymous_types = true
+csharp_new_line_before_members_in_object_initializers = false
+csharp_new_line_before_open_brace = all
+csharp_new_line_between_query_expression_clauses = true
+
+# Indentation preferences
+csharp_indent_block_contents = true
+csharp_indent_braces = false
+csharp_indent_case_contents = true
+csharp_indent_case_contents_when_block = true
+csharp_indent_labels = no_change
+csharp_indent_switch_labels = true
+
+# Space preferences
+csharp_space_after_cast = false
+csharp_space_after_colon_in_inheritance_clause = true
+csharp_space_after_comma = true
+csharp_space_after_dot = false
+csharp_space_after_keywords_in_control_flow_statements = true
+csharp_space_after_semicolon_in_for_statement = true
+csharp_space_around_binary_operators = before_and_after
+csharp_space_around_declaration_statements = false
+csharp_space_before_colon_in_inheritance_clause = true
+csharp_space_before_comma = false
+csharp_space_before_dot = false
+csharp_space_before_open_square_brackets = false
+csharp_space_before_semicolon_in_for_statement = false
+csharp_space_between_empty_square_brackets = false
+csharp_space_between_method_call_empty_parameter_list_parentheses = false
+csharp_space_between_method_call_name_and_opening_parenthesis = false
+csharp_space_between_method_call_parameter_list_parentheses = false
+csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
+csharp_space_between_method_declaration_name_and_open_parenthesis = false
+csharp_space_between_method_declaration_parameter_list_parentheses = false
+csharp_space_between_parentheses = expressions
+csharp_space_between_square_brackets = false
+
+# Wrapping preferences
+csharp_preserve_single_line_blocks = true
+csharp_preserve_single_line_statements = true
+
+#### Naming styles ####
+
+# Naming rules
+
+dotnet_naming_rule.interface_should_be_begins_with_i.severity = suggestion
+dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface
+dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i
+
+dotnet_naming_rule.type_parameter_should_be_begins_with_t.severity = suggestion
+dotnet_naming_rule.type_parameter_should_be_begins_with_t.symbols = type_parameter
+dotnet_naming_rule.type_parameter_should_be_begins_with_t.style = begins_with_t
+
+dotnet_naming_rule.locals_should_be_camel_case.severity = suggestion
+dotnet_naming_rule.locals_should_be_camel_case.symbols = local
+dotnet_naming_rule.locals_should_be_camel_case.style = camel_case
+
+dotnet_naming_rule.static_field_should_be_pascal_case.severity = suggestion
+dotnet_naming_rule.static_field_should_be_pascal_case.symbols = static_field
+dotnet_naming_rule.static_field_should_be_pascal_case.style = pascal_case
+
+dotnet_naming_rule.const_field_should_be_pascal_case.severity = suggestion
+dotnet_naming_rule.const_field_should_be_pascal_case.symbols = const_field
+dotnet_naming_rule.const_field_should_be_pascal_case.style = pascal_case
+
+dotnet_naming_rule.private_field_members_should_be_underscore_camel_case.severity = suggestion
+dotnet_naming_rule.private_field_members_should_be_underscore_camel_case.symbols = private_field
+dotnet_naming_rule.private_field_members_should_be_underscore_camel_case.style = _camel_case
+
+dotnet_naming_rule.field_should_be_camel_case.severity = suggestion
+dotnet_naming_rule.field_should_be_camel_case.symbols = field
+dotnet_naming_rule.field_should_be_camel_case.style = camel_case
+
+dotnet_naming_rule.types_should_be_pascal_case.severity = suggestion
+dotnet_naming_rule.types_should_be_pascal_case.symbols = types
+dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case
+
+dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = suggestion
+dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members
+dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case
+
+# Symbol specifications
+
+dotnet_naming_symbols.interface.applicable_kinds = interface
+dotnet_naming_symbols.interface.applicable_accessibilities = *
+dotnet_naming_symbols.interface.required_modifiers =
+
+dotnet_naming_symbols.local.applicable_kinds = local, local_function
+dotnet_naming_symbols.local.applicable_accessibilities = *
+dotnet_naming_symbols.local.required_modifiers =
+dotnet_naming_symbols.type_parameter.applicable_kinds = type_parameter
+dotnet_naming_symbols.type_parameter.applicable_accessibilities = *
+dotnet_naming_symbols.type_parameter.required_modifiers =
+dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum, delegate
+dotnet_naming_symbols.types.applicable_accessibilities = *
+dotnet_naming_symbols.types.required_modifiers =
+dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method
+dotnet_naming_symbols.non_field_members.applicable_accessibilities = *
+dotnet_naming_symbols.non_field_members.required_modifiers =
+dotnet_naming_symbols.private_field.applicable_kinds = field
+dotnet_naming_symbols.private_field.applicable_accessibilities = private, private_protected
+dotnet_naming_symbols.private_field.required_modifiers =
+dotnet_naming_symbols.field.applicable_kinds = field
+dotnet_naming_symbols.field.applicable_accessibilities = public, protected, internal, protected_internal, private_protected
+dotnet_naming_symbols.field.required_modifiers =
+dotnet_naming_symbols.static_field.applicable_kinds = field
+dotnet_naming_symbols.static_field.applicable_accessibilities =
+dotnet_naming_symbols.static_field.required_modifiers = static
+
+dotnet_naming_symbols.const_field.applicable_kinds = field
+dotnet_naming_symbols.const_field.applicable_accessibilities = *
+dotnet_naming_symbols.const_field.required_modifiers = const
+
+# Naming styles
+
+# dotnet_naming_style.pascal_case.required_prefix =
+# dotnet_naming_style.pascal_case.required_suffix =
+# dotnet_naming_style.pascal_case.word_separator =
+dotnet_naming_style.pascal_case.capitalization = pascal_case
+
+# dotnet_naming_style.camel_case.required_prefix =
+# dotnet_naming_style.camel_case.required_suffix =
+# dotnet_naming_style.camel_case.word_separator =
+dotnet_naming_style.camel_case.capitalization = camel_case
+
+dotnet_naming_style._camel_case.required_prefix = _
+# dotnet_naming_style._camel_case.required_suffix =
+# dotnet_naming_style._camel_case.word_separator =
+dotnet_naming_style._camel_case.capitalization = camel_case
+
+dotnet_naming_style.begins_with_i.required_prefix = I
+# dotnet_naming_style.begins_with_i.required_suffix =
+# dotnet_naming_style.begins_with_i.word_separator =
+dotnet_naming_style.begins_with_i.capitalization = pascal_case
+
+dotnet_naming_style.begins_with_t.required_prefix = T
+# dotnet_naming_style.begins_with_t.required_suffix =
+# dotnet_naming_style.begins_with_t.word_separator =
+dotnet_naming_style.begins_with_t.capitalization = pascal_case
+
+dotnet_diagnostic.ide0058.severity = none
+
+# CodeQuality
+# CA1000: Do not declare static members on generic types
+# dotnet_diagnostic.CA1000.severity = warning
+
+# CA1001: Types that own disposable fields should be disposable
+# dotnet_diagnostic.CA1001.severity = warning
+
+# CA1003: Use generic event handler instances
+# dotnet_diagnostic.CA1003.severity = none
+
+# CA1008: Enums should have zero value
+# dotnet_diagnostic.CA1008.severity = none
+
+# CA1010: Collections should implement generic interface
+# dotnet_diagnostic.CA1010.severity = warning
+
+# CA1012: Abstract types should not have constructors
+# dotnet_diagnostic.CA1012.severity = none
+
+# CA1014: Mark assemblies with CLSCompliant
+# dotnet_diagnostic.CA1014.severity = none
+
+# CA1016: Mark assemblies with assembly version
+# dotnet_diagnostic.CA1016.severity = warning
+
+# CA1017: Mark assemblies with ComVisible
+# dotnet_diagnostic.CA1017.severity = none
+
+# CA1018: Mark attributes with AttributeUsageAttribute
+# dotnet_diagnostic.CA1018.severity = warning
+
+# CA1019: Define accessors for attribute arguments
+# dotnet_diagnostic.CA1019.severity = none
+
+# CA1024: Use properties where appropriate
+# dotnet_diagnostic.CA1024.severity = none
+
+# CA1027: Mark enums with FlagsAttribute
+# dotnet_diagnostic.CA1027.severity = none
+
+# CA1028: Enum Storage should be Int32
+# dotnet_diagnostic.CA1028.severity = warning
+
+# CA1030: Use events where appropriate
+# dotnet_diagnostic.CA1030.severity = warning
+
+# CA1031: Do not catch general exception types
+# dotnet_diagnostic.CA1031.severity = warning
+
+# CA1032: Implement standard exception constructors
+# dotnet_diagnostic.CA1032.severity = warning
+
+# CA1033: Interface methods should be callable by child types
+# dotnet_diagnostic.CA1033.severity = none
+
+# CA1034: Nested types should not be visible
+# dotnet_diagnostic.CA1034.severity = warning
+
+# CA1036: Override methods on comparable types
+# dotnet_diagnostic.CA1036.severity = warning
+
+# CA1040: Avoid empty interfaces
+# dotnet_diagnostic.CA1040.severity = warning
+
+# CA1041: Provide ObsoleteAttribute message
+# dotnet_diagnostic.CA1041.severity = warning
+
+# CA1043: Use Integral Or String Argument For Indexers
+# dotnet_diagnostic.CA1043.severity = warning
+
+# CA1044: Properties should not be write only
+# dotnet_diagnostic.CA1044.severity = warning
+
+# CA1050: Declare types in namespaces
+# dotnet_diagnostic.CA1050.severity = none
+
+# CA1051: Do not declare visible instance fields
+# dotnet_diagnostic.CA1051.severity = warning
+
+# CA1052: Static holder types should be Static or NotInheritable
+# dotnet_diagnostic.CA1052.severity = warning
+
+# CA1054: Uri parameters should not be strings
+# dotnet_diagnostic.CA1054.severity = warning
+
+# CA1055: Uri return values should not be strings
+# dotnet_diagnostic.CA1055.severity = warning
+
+# CA1056: Uri properties should not be strings
+# dotnet_diagnostic.CA1056.severity = warning
+
+# CA1060: Move pinvokes to native methods class
+# dotnet_diagnostic.CA1060.severity = none
+
+# CA1061: Do not hide base class methods
+# dotnet_diagnostic.CA1061.severity = warning
+
+# CA1062: Validate arguments of public methods
+dotnet_diagnostic.ca1062.severity = none
+
+# CA1063: Implement IDisposable Correctly
+# dotnet_diagnostic.CA1063.severity = none
+
+# CA1064: Exceptions should be public
+# dotnet_diagnostic.CA1064.severity = warning
+
+# CA1065: Do not raise exceptions in unexpected locations
+# dotnet_diagnostic.CA1065.severity = warning
+
+# CA1066: Type {0} should implement IEquatable because it overrides Equals
+# dotnet_diagnostic.CA1066.severity = warning
+
+# CA1067: Override Object.Equals(object) when implementing IEquatable
+# dotnet_diagnostic.CA1067.severity = warning
+
+# CA1068: CancellationToken parameters must come last
+# dotnet_diagnostic.CA1068.severity = warning
+
+# CA1200: Avoid using cref tags with a prefix
+# dotnet_diagnostic.CA1200.severity = warning
+
+# CA1501: Avoid excessive inheritance
+# dotnet_diagnostic.CA1501.severity = none
+
+# CA1502: Avoid excessive complexity
+# dotnet_diagnostic.CA1502.severity = none
+
+# CA1505: Avoid unmaintainable code
+# dotnet_diagnostic.CA1505.severity = none
+
+# CA1506: Avoid excessive class coupling
+# dotnet_diagnostic.CA1506.severity = none
+
+# CA1507: Use nameof to express symbol names
+# dotnet_diagnostic.CA1507.severity = warning
+
+# CA1508: Avoid dead conditional code
+# dotnet_diagnostic.CA1508.severity = none
+
+# CA1509: Invalid entry in code metrics rule specification file
+# dotnet_diagnostic.CA1509.severity = none
+
+# CA1707: Identifiers should not contain underscores
+# dotnet_diagnostic.CA1707.severity = none
+
+# CA1708: Identifiers should differ by more than case
+# dotnet_diagnostic.CA1708.severity = none
+
+# CA1710: Identifiers should have correct suffix
+# dotnet_diagnostic.CA1710.severity = warning
+
+# CA1711: Identifiers should not have incorrect suffix
+# dotnet_diagnostic.CA1711.severity = none
+
+# CA1712: Do not prefix enum values with type name
+# dotnet_diagnostic.CA1712.severity = warning
+
+# CA1714: Flags enums should have plural names
+# dotnet_diagnostic.CA1714.severity = warning
+
+# CA1715: Identifiers should have correct prefix
+# dotnet_diagnostic.CA1715.severity = warning
+
+# CA1716: Identifiers should not match keywords
+# dotnet_diagnostic.CA1716.severity = warning
+
+# CA1717: Only FlagsAttribute enums should have plural names
+# dotnet_diagnostic.CA1717.severity = warning
+
+# CA1720: Identifier contains type name
+# dotnet_diagnostic.CA1720.severity = warning
+
+# CA1721: Property names should not match get methods
+# dotnet_diagnostic.CA1721.severity = warning
+
+# CA1724: Type names should not match namespaces
+# dotnet_diagnostic.CA1724.severity = warning
+
+# CA1725: Parameter names should match base declaration
+# dotnet_diagnostic.CA1725.severity = none
+
+# CA1801: Review unused parameters
+# dotnet_diagnostic.CA1801.severity = warning
+
+# CA1802: Use literals where appropriate
+# dotnet_diagnostic.CA1802.severity = warning
+
+# CA1806: Do not ignore method results
+# dotnet_diagnostic.CA1806.severity = warning
+
+# CA1812: Avoid uninstantiated internal classes
+# dotnet_diagnostic.CA1812.severity = none
+
+# CA1814: Prefer jagged arrays over multidimensional
+# dotnet_diagnostic.CA1814.severity = warning
+
+# CA1815: Override equals and operator equals on value types
+# dotnet_diagnostic.CA1815.severity = warning
+
+# CA1819: Properties should not return arrays
+# dotnet_diagnostic.CA1819.severity = warning
+
+# CA1821: Remove empty Finalizers
+# dotnet_diagnostic.CA1821.severity = warning
+
+# CA1822: Mark members as static
+# dotnet_diagnostic.CA1822.severity = warning
+
+# CA1823: Avoid unused private fields
+# dotnet_diagnostic.CA1823.severity = warning
+
+# CA2007: Consider calling ConfigureAwait on the awaited task
+dotnet_diagnostic.ca2007.severity = none
+
+# CA2119: Seal methods that satisfy private interfaces
+# dotnet_diagnostic.CA2119.severity = warning
+
+# CA2200: Rethrow to preserve stack details.
+# dotnet_diagnostic.CA2200.severity = warning
+
+# CA2211: Non-constant fields should not be visible
+# dotnet_diagnostic.CA2211.severity = warning
+
+# CA2214: Do not call overridable methods in constructors
+# dotnet_diagnostic.CA2214.severity = warning
+
+# CA2217: Do not mark enums with FlagsAttribute
+# dotnet_diagnostic.CA2217.severity = none
+
+# CA2218: Override GetHashCode on overriding Equals
+# dotnet_diagnostic.CA2218.severity = warning
+
+# CA2219: Do not raise exceptions in finally clauses
+# dotnet_diagnostic.CA2219.severity = warning
+
+# CA2224: Override Equals on overloading operator equals
+# dotnet_diagnostic.CA2224.severity = warning
+
+# CA2225: Operator overloads have named alternates
+# dotnet_diagnostic.CA2225.severity = warning
+
+# CA2226: Operators should have symmetrical overloads
+# dotnet_diagnostic.CA2226.severity = warning
+
+# CA2227: Collection properties should be read only
+# dotnet_diagnostic.CA2227.severity = warning
+
+# CA2231: Overload operator equals on overriding value type Equals
+# dotnet_diagnostic.CA2231.severity = warning
+
+# CA2234: Pass system uri objects instead of strings
+# dotnet_diagnostic.CA2234.severity = warning
+
+# CA2244: Do not duplicate indexed element initializations
+# dotnet_diagnostic.CA2244.severity = warning
+
+# CA2245: Do not assign a property to itself.
+# dotnet_diagnostic.CA2245.severity = warning
+
+# CA2246: Assigning symbol and its member in the same statement.
+# dotnet_diagnostic.CA2246.severity = warning
+
+# NetCore
+
+# CA1303: Do not pass literals as localized parameters
+# dotnet_diagnostic.CA1303.severity = none
+
+# CA1304: Specify CultureInfo
+# dotnet_diagnostic.CA1304.severity = none
+
+# CA1305: Specify IFormatProvider
+# dotnet_diagnostic.CA1305.severity = none
+
+# CA1307: Specify StringComparison
+# dotnet_diagnostic.CA1307.severity = warning
+
+# CA1308: Normalize strings to uppercase
+# dotnet_diagnostic.CA1308.severity = warning
+
+# CA1309: Use ordinal stringcomparison
+# dotnet_diagnostic.CA1309.severity = none
+
+# CA1401: P/Invokes should not be visible
+# dotnet_diagnostic.CA1401.severity = warning
+
+# CA1810: Initialize reference type static fields inline
+# dotnet_diagnostic.CA1810.severity = warning
+
+# CA1813: Avoid unsealed attributes
+# dotnet_diagnostic.CA1813.severity = none
+
+# CA1816: Dispose methods should call SuppressFinalize
+# dotnet_diagnostic.CA1816.severity = none
+
+# CA1820: Test for empty strings using string length
+# dotnet_diagnostic.CA1820.severity = warning
+
+# CA1824: Mark assemblies with NeutralResourcesLanguageAttribute
+# dotnet_diagnostic.CA1824.severity = warning
+
+# CA1825: Avoid zero-length array allocations.
+# dotnet_diagnostic.CA1825.severity = warning
+
+# CA1826: Do not use Enumerable methods on indexable collections. Instead use the collection directly
+# dotnet_diagnostic.CA1826.severity = warning
+
+# CA1827: Do not use Count() or LongCount() when Any() can be used
+# dotnet_diagnostic.CA1827.severity = warning
+
+# CA1828: Do not use CountAsync() or LongCountAsync() when AnyAsync() can be used
+# dotnet_diagnostic.CA1828.severity = warning
+
+# CA1829: Use Length/Count property instead of Count() when available
+# dotnet_diagnostic.CA1829.severity = warning
+
+# CA2000: Dispose objects before losing scope
+# dotnet_diagnostic.CA2000.severity = warning
+
+# CA2002: Do not lock on objects with weak identity
+# dotnet_diagnostic.CA2002.severity = warning
+
+# CA2008: Do not create tasks without passing a TaskScheduler
+# dotnet_diagnostic.CA2008.severity = warning
+
+# CA2009: Do not call ToImmutableCollection on an ImmutableCollection value
+# dotnet_diagnostic.CA2009.severity = warning
+
+# CA2010: Always consume the value returned by methods marked with PreserveSigAttribute
+# dotnet_diagnostic.CA2010.severity = warning
+
+# CA2100: Review SQL queries for security vulnerabilities
+# dotnet_diagnostic.CA2100.severity = warning
+
+# CA2101: Specify marshaling for P/Invoke string arguments
+# dotnet_diagnostic.CA2101.severity = warning
+
+# CA2201: Do not raise reserved exception types
+# dotnet_diagnostic.CA2201.severity = none
+
+# CA2207: Initialize value type static fields inline
+# dotnet_diagnostic.CA2207.severity = warning
+
+# CA2208: Instantiate argument exceptions correctly
+# dotnet_diagnostic.CA2208.severity = warning
+
+# CA2213: Disposable fields should be disposed
+# dotnet_diagnostic.CA2213.severity = warning
+
+# CA2216: Disposable types should declare finalizer
+# dotnet_diagnostic.CA2216.severity = warning
+
+# CA2229: Implement serialization constructors
+# dotnet_diagnostic.CA2229.severity = warning
+
+# CA2235: Mark all non-serializable fields
+# dotnet_diagnostic.CA2235.severity = warning
+
+# CA2237: Mark ISerializable types with serializable
+# dotnet_diagnostic.CA2237.severity = warning
+
+# CA2241: Provide correct arguments to formatting methods
+# dotnet_diagnostic.CA2241.severity = warning
+
+# CA2242: Test for NaN correctly
+# dotnet_diagnostic.CA2242.severity = warning
+
+# CA2243: Attribute string literals should parse correctly
+# dotnet_diagnostic.CA2243.severity = warning
+
+# CA2300: Do not use insecure deserializer BinaryFormatter
+# dotnet_diagnostic.CA2300.severity = none
+
+# CA2301: Do not call BinaryFormatter.Deserialize without first setting BinaryFormatter.Binder
+# dotnet_diagnostic.CA2301.severity = none
+
+# CA2302: Ensure BinaryFormatter.Binder is set before calling BinaryFormatter.Deserialize
+# dotnet_diagnostic.CA2302.severity = none
+
+# CA2305: Do not use insecure deserializer LosFormatter
+# dotnet_diagnostic.CA2305.severity = none
+
+# CA2310: Do not use insecure deserializer NetDataContractSerializer
+# dotnet_diagnostic.CA2310.severity = none
+
+# CA2311: Do not deserialize without first setting NetDataContractSerializer.Binder
+# dotnet_diagnostic.CA2311.severity = none
+
+# CA2312: Ensure NetDataContractSerializer.Binder is set before deserializing
+# dotnet_diagnostic.CA2312.severity = none
+
+# CA2315: Do not use insecure deserializer ObjectStateFormatter
+# dotnet_diagnostic.CA2315.severity = none
+
+# CA2321: Do not deserialize with JavaScriptSerializer using a SimpleTypeResolver
+# dotnet_diagnostic.CA2321.severity = none
+
+# CA2322: Ensure JavaScriptSerializer is not initialized with SimpleTypeResolver before deserializing
+# dotnet_diagnostic.CA2322.severity = none
+
+# CA2326: Do not use TypeNameHandling values other than None
+# dotnet_diagnostic.CA2326.severity = none
+
+# CA2327: Do not use insecure JsonSerializerSettings
+# dotnet_diagnostic.CA2327.severity = none
+
+# CA2328: Ensure that JsonSerializerSettings are secure
+# dotnet_diagnostic.CA2328.severity = none
+
+# CA2329: Do not deserialize with JsonSerializer using an insecure configuration
+# dotnet_diagnostic.CA2329.severity = none
+
+# CA2330: Ensure that JsonSerializer has a secure configuration when deserializing
+# dotnet_diagnostic.CA2330.severity = none
+
+# CA3001: Review code for SQL injection vulnerabilities
+# dotnet_diagnostic.CA3001.severity = none
+
+# CA3002: Review code for XSS vulnerabilities
+# dotnet_diagnostic.CA3002.severity = none
+
+# CA3003: Review code for file path injection vulnerabilities
+# dotnet_diagnostic.CA3003.severity = none
+
+# CA3004: Review code for information disclosure vulnerabilities
+# dotnet_diagnostic.CA3004.severity = none
+
+# CA3005: Review code for LDAP injection vulnerabilities
+# dotnet_diagnostic.CA3005.severity = none
+
+# CA3006: Review code for process command injection vulnerabilities
+# dotnet_diagnostic.CA3006.severity = none
+
+# CA3007: Review code for open redirect vulnerabilities
+# dotnet_diagnostic.CA3007.severity = none
+
+# CA3008: Review code for XPath injection vulnerabilities
+# dotnet_diagnostic.CA3008.severity = none
+
+# CA3009: Review code for XML injection vulnerabilities
+# dotnet_diagnostic.CA3009.severity = none
+
+# CA3010: Review code for XAML injection vulnerabilities
+# dotnet_diagnostic.CA3010.severity = none
+
+# CA3011: Review code for DLL injection vulnerabilities
+# dotnet_diagnostic.CA3011.severity = none
+
+# CA3012: Review code for regex injection vulnerabilities
+# dotnet_diagnostic.CA3012.severity = none
+
+# CA3061: Do Not Add Schema By URL
+# dotnet_diagnostic.CA3061.severity = warning
+
+# CA5350: Do Not Use Weak Cryptographic Algorithms
+# dotnet_diagnostic.CA5350.severity = warning
+
+# CA5351: Do Not Use Broken Cryptographic Algorithms
+# dotnet_diagnostic.CA5351.severity = warning
+
+# CA5358: Do Not Use Unsafe Cipher Modes
+# dotnet_diagnostic.CA5358.severity = none
+
+# CA5359: Do Not Disable Certificate Validation
+# dotnet_diagnostic.CA5359.severity = warning
+
+# CA5360: Do Not Call Dangerous Methods In Deserialization
+# dotnet_diagnostic.CA5360.severity = warning
+
+# CA5361: Do Not Disable SChannel Use of Strong Crypto
+# dotnet_diagnostic.CA5361.severity = warning
+
+# CA5362: Do Not Refer Self In Serializable Class
+# dotnet_diagnostic.CA5362.severity = none
+
+# CA5363: Do Not Disable Request Validation
+# dotnet_diagnostic.CA5363.severity = warning
+
+# CA5364: Do Not Use Deprecated Security Protocols
+# dotnet_diagnostic.CA5364.severity = warning
+
+# CA5365: Do Not Disable HTTP Header Checking
+# dotnet_diagnostic.CA5365.severity = warning
+
+# CA5366: Use XmlReader For DataSet Read Xml
+# dotnet_diagnostic.CA5366.severity = warning
+
+# CA5367: Do Not Serialize Types With Pointer Fields
+# dotnet_diagnostic.CA5367.severity = none
+
+# CA5368: Set ViewStateUserKey For Classes Derived From Page
+# dotnet_diagnostic.CA5368.severity = warning
+
+# CA5369: Use XmlReader For Deserialize
+# dotnet_diagnostic.CA5369.severity = warning
+
+# CA5370: Use XmlReader For Validating Reader
+# dotnet_diagnostic.CA5370.severity = warning
+
+# CA5371: Use XmlReader For Schema Read
+# dotnet_diagnostic.CA5371.severity = warning
+
+# CA5372: Use XmlReader For XPathDocument
+# dotnet_diagnostic.CA5372.severity = warning
+
+# CA5373: Do not use obsolete key derivation function
+# dotnet_diagnostic.CA5373.severity = warning
+
+# CA5374: Do Not Use XslTransform
+# dotnet_diagnostic.CA5374.severity = warning
+
+# CA5375: Do Not Use Account Shared Access Signature
+# dotnet_diagnostic.CA5375.severity = none
+
+# CA5376: Use SharedAccessProtocol HttpsOnly
+# dotnet_diagnostic.CA5376.severity = warning
+
+# CA5377: Use Container Level Access Policy
+# dotnet_diagnostic.CA5377.severity = warning
+
+# CA5378: Do not disable ServicePointManagerSecurityProtocols
+# dotnet_diagnostic.CA5378.severity = warning
+
+# CA5379: Do Not Use Weak Key Derivation Function Algorithm
+# dotnet_diagnostic.CA5379.severity = warning
+
+# CA5380: Do Not Add Certificates To Root Store
+# dotnet_diagnostic.CA5380.severity = warning
+
+# CA5381: Ensure Certificates Are Not Added To Root Store
+# dotnet_diagnostic.CA5381.severity = warning
+
+# CA5382: Use Secure Cookies In ASP.Net Core
+# dotnet_diagnostic.CA5382.severity = none
+
+# CA5383: Ensure Use Secure Cookies In ASP.Net Core
+# dotnet_diagnostic.CA5383.severity = none
+
+# CA5384: Do Not Use Digital Signature Algorithm (DSA)
+# dotnet_diagnostic.CA5384.severity = warning
+
+# CA5385: Use Rivest–Shamir–Adleman (RSA) Algorithm With Sufficient Key Size
+# dotnet_diagnostic.CA5385.severity = warning
+
+# CA5386: Avoid hardcoding SecurityProtocolType value
+# dotnet_diagnostic.CA5386.severity = none
+
+# CA5387: Do Not Use Weak Key Derivation Function With Insufficient Iteration Count
+# dotnet_diagnostic.CA5387.severity = none
+
+# CA5388: Ensure Sufficient Iteration Count When Using Weak Key Derivation Function
+# dotnet_diagnostic.CA5388.severity = none
+
+# CA5389: Do Not Add Archive Item's Path To The Target File System Path
+# dotnet_diagnostic.CA5389.severity = none
+
+# CA5390: Do not hard-code encryption key
+# dotnet_diagnostic.CA5390.severity = none
+
+# CA5391: Use antiforgery tokens in ASP.NET Core MVC controllers
+# dotnet_diagnostic.CA5391.severity = none
+
+# CA5392: Use DefaultDllImportSearchPaths attribute for P/Invokes
+# dotnet_diagnostic.CA5392.severity = none
+
+# CA5393: Do not use unsafe DllImportSearchPath value
+# dotnet_diagnostic.CA5393.severity = none
+
+# CA5394: Do not use insecure randomness
+# dotnet_diagnostic.CA5394.severity = none
+
+# CA5395: Miss HttpVerb attribute for action methods
+# dotnet_diagnostic.CA5395.severity = none
+
+# CA5396: Set HttpOnly to true for HttpCookie
+# dotnet_diagnostic.CA5396.severity = none
+
+# CA5397: Do not use deprecated SslProtocols values
+# dotnet_diagnostic.CA5397.severity = warning
+
+# CA5398: Avoid hardcoded SslProtocols values
+# dotnet_diagnostic.CA5398.severity = none
+
+# CA5399: HttpClients should enable certificate revocation list checks
+# dotnet_diagnostic.CA5399.severity = none
+
+# CA5400: Ensure HttpClient certificate revocation list check is not disabled
+# dotnet_diagnostic.CA5400.severity = none
+
+# CA5401: Do not use CreateEncryptor with non-default IV
+# dotnet_diagnostic.CA5401.severity = none
+
+# CA5402: Use CreateEncryptor with the default IV
+# dotnet_diagnostic.CA5402.severity = none
+
+# CA5403: Do not hard-code certificate
+# dotnet_diagnostic.CA5403.severity = none
+
+# NetFramework
+
+# CA1058: Types should not extend certain base types
+# dotnet_diagnostic.CA1058.severity = warning
+
+# CA2153: Do Not Catch Corrupted State Exceptions
+# dotnet_diagnostic.CA2153.severity = warning
+
+# CA3075: Insecure DTD processing in XML
+# dotnet_diagnostic.CA3075.severity = warning
+
+# CA3076: Insecure XSLT script processing.
+# dotnet_diagnostic.CA3076.severity = warning
+
+# CA3077: Insecure Processing in API Design, XmlDocument and XmlTextReader
+# dotnet_diagnostic.CA3077.severity = warning
+
+# CA3147: Mark Verb Handlers With Validate Antiforgery Token
+# dotnet_diagnostic.CA3147.severity = warning
+
+# PublicApi
+
+# RS0016: Add public types and members to the declared API
+# dotnet_diagnostic.RS0016.severity = warning
+
+# RS0017: Remove deleted types and members from the declared API
+# dotnet_diagnostic.RS0017.severity = warning
+
+# RS0022: Constructor make noninheritable base class inheritable
+# dotnet_diagnostic.RS0022.severity = warning
+
+# RS0024: The contents of the public API files are invalid
+# dotnet_diagnostic.RS0024.severity = warning
+
+# RS0025: Do not duplicate symbols in public API files
+# dotnet_diagnostic.RS0025.severity = warning
+
+# RS0026: Do not add multiple public overloads with optional parameters
+# dotnet_diagnostic.RS0026.severity = warning
+
+# RS0027: Public API with optional parameter(s) should have the most parameters amongst its public overloads.
+# dotnet_diagnostic.RS0027.severity = warning
# ReSharper properties
-resharper_accessor_declaration_braces=end_of_line
-resharper_align_linq_query=true
-resharper_align_multiline_argument=true
-resharper_align_multiline_calls_chain=true
-resharper_align_multiline_extends_list=true
-resharper_align_multiline_for_stmt=true
-resharper_align_multiline_parameter=true
-resharper_align_multiple_declaration=true
-resharper_align_multline_type_parameter_constrains=true
-resharper_align_multline_type_parameter_list=true
-resharper_align_tuple_components=true
-resharper_autodetect_indent_settings=true
-resharper_constructor_or_destructor_body=expression_body
-resharper_csharp_anonymous_method_declaration_braces=end_of_line
-resharper_csharp_outdent_commas=true
-resharper_csharp_outdent_dots=true
-resharper_csharp_space_within_parentheses=true
-resharper_csharp_wrap_after_declaration_lpar=true
-resharper_csharp_wrap_after_invocation_lpar=true
-resharper_csharp_wrap_before_binary_opsign=true
-resharper_csharp_wrap_before_declaration_rpar=true
-resharper_csharp_wrap_before_invocation_rpar=true
-resharper_enforce_line_ending_style=true
-resharper_initializer_braces=end_of_line
-resharper_int_align_switch_expressions=true
-resharper_int_align_switch_sections=true
-resharper_keep_existing_enum_arrangement=true
-resharper_keep_existing_switch_expression_arrangement=false
-resharper_max_initializer_elements_on_line=2
-resharper_method_or_operator_body=expression_body
-resharper_outdent_binary_ops=true
-resharper_place_comments_at_first_column=true
-resharper_place_simple_enum_on_single_line=true
-resharper_space_around_arrow_op=true
-resharper_space_within_single_line_array_initializer_braces=true
-resharper_use_heuristics_for_body_style=false
-resharper_use_indent_from_vs=false
-resharper_wrap_lines=true
-resharper_xmldoc_allow_far_alignment=true
-resharper_xmldoc_attribute_style=on_single_line
-resharper_xmldoc_indent_text=ZeroIndent
-resharper_xmldoc_max_blank_lines_between_tags=1
-resharper_xmldoc_pi_attribute_style=on_single_line
-resharper_xmldoc_space_after_last_pi_attribute=true
+resharper_align_linq_query = true
+resharper_align_multiline_argument = true
+resharper_align_multiline_array_and_object_initializer = false
+resharper_align_multiline_binary_expressions_chain = false
+resharper_align_multiline_calls_chain = true
+resharper_align_multiline_expression = true
+resharper_align_multiline_extends_list = true
+resharper_align_multiline_for_stmt = true
+resharper_align_multiline_parameter = true
+resharper_align_multiline_switch_expression = false
+resharper_align_multiple_declaration = true
+resharper_align_multline_type_parameter_constrains = true
+resharper_align_multline_type_parameter_list = true
+resharper_align_tuple_components = true
+resharper_arguments_anonymous_function = positional
+resharper_autodetect_indent_settings = true
+resharper_braces_for_for = not_required
+resharper_braces_for_foreach = not_required
+resharper_braces_for_ifelse = not_required_for_both
+resharper_braces_for_while = not_required
+resharper_braces_redundant = false
+resharper_constructor_or_destructor_body = block_body
+resharper_continuous_indent_multiplier = 1
+resharper_cpp_empty_block_style = multiline
+resharper_cpp_outdent_commas = false
+resharper_cpp_outdent_dots = false
+resharper_cpp_wrap_after_declaration_lpar = false
+resharper_cpp_wrap_after_invocation_lpar = false
+resharper_cpp_wrap_before_declaration_rpar = false
+resharper_cpp_wrap_before_invocation_rpar = false
+resharper_csharp_align_multiline_argument = true
+resharper_csharp_align_multiline_binary_expressions_chain = true
+resharper_csharp_align_multiline_expression = false
+resharper_csharp_brace_style = next_line
+resharper_csharp_empty_block_style = multiline
+resharper_csharp_outdent_commas = true
+resharper_csharp_outdent_dots = true
+resharper_csharp_place_comments_at_first_column = true
+resharper_csharp_wrap_after_declaration_lpar = true
+resharper_csharp_wrap_after_invocation_lpar = true
+resharper_csharp_wrap_before_binary_opsign = true
+resharper_csharp_wrap_before_declaration_rpar = true
+resharper_csharp_wrap_before_invocation_rpar = true
+resharper_csharp_wrap_multiple_declaration_style = chop_if_long
+resharper_empty_block_style = together_same_line
+resharper_indent_anonymous_method_block = false
+resharper_int_align_switch_expressions = true
+resharper_int_align_switch_sections = true
+resharper_keep_existing_declaration_block_arrangement = false
+resharper_keep_existing_embedded_block_arrangement = false
+resharper_keep_existing_enum_arrangement = true
+resharper_keep_existing_invocation_parens_arrangement = true
+resharper_keep_existing_linebreaks = true
+resharper_keep_existing_switch_expression_arrangement = false
+resharper_keep_user_linebreaks = true
+resharper_max_initializer_elements_on_line = 2
+resharper_method_or_operator_body = block_body
+resharper_outdent_binary_ops = true
+resharper_outdent_commas = true
+resharper_outdent_dots = true
+resharper_space_around_arrow_op = true
+resharper_space_within_single_line_array_initializer_braces = true
+resharper_use_heuristics_for_body_style = true
+resharper_use_indent_from_vs = false
+resharper_wrap_after_declaration_lpar = true
+resharper_wrap_after_invocation_lpar = true
+resharper_wrap_arguments_style = wrap_if_long
+resharper_wrap_before_declaration_rpar = true
+resharper_wrap_before_invocation_rpar = true
+resharper_wrap_chained_method_calls = wrap_if_long
+resharper_wrap_multiple_declaration_style = chop_if_long
+resharper_wrap_object_and_collection_initializer_style = chop_if_long
+resharper_xmldoc_attribute_style = on_single_line
+resharper_xmldoc_pi_attribute_style = on_single_line
+resharper_xmldoc_space_after_last_pi_attribute = true
+resharper_xmldoc_space_before_self_closing = true
# ReSharper inspection severities
-resharper_annotate_can_be_null_parameter_highlighting=warning
-resharper_annotate_can_be_null_type_member_highlighting=warning
-resharper_arrange_missing_parentheses_highlighting=warning
-resharper_arrange_this_qualifier_highlighting=warning
-resharper_built_in_type_reference_style_for_member_access_highlighting=error
-resharper_built_in_type_reference_style_highlighting=error
-resharper_enforce_do_while_statement_braces_highlighting=warning
-resharper_enforce_fixed_statement_braces_highlighting=warning
-resharper_enforce_foreach_statement_braces_highlighting=warning
-resharper_enforce_for_statement_braces_highlighting=warning
-resharper_enforce_if_statement_braces_highlighting=warning
-resharper_enforce_lock_statement_braces_highlighting=warning
-resharper_enforce_using_statement_braces_highlighting=warning
-resharper_enforce_while_statement_braces_highlighting=warning
-resharper_redundant_default_member_initializer_highlighting=hint
-resharper_remove_redundant_braces_highlighting=warning
-resharper_suggest_var_or_type_built_in_types_highlighting=warning
-resharper_suggest_var_or_type_elsewhere_highlighting=warning
-resharper_suggest_var_or_type_simple_types_highlighting=warning
-resharper_unnecessary_whitespace_highlighting=warning
-resharper_use_null_propagation_when_possible_highlighting=suggestion
-resharper_web_config_module_not_resolved_highlighting=warning
-resharper_web_config_type_not_resolved_highlighting=warning
-resharper_web_config_wrong_module_highlighting=warning
+resharper_annotate_can_be_null_parameter_highlighting = warning
+resharper_annotate_can_be_null_type_member_highlighting = warning
+resharper_arrange_constructor_or_destructor_body_highlighting = none
+resharper_arrange_method_or_operator_body_highlighting = none
+resharper_arrange_redundant_parentheses_highlighting = hint
+resharper_arrange_this_qualifier_highlighting = hint
+resharper_arrange_type_member_modifiers_highlighting = hint
+resharper_arrange_type_modifiers_highlighting = hint
+resharper_built_in_type_reference_style_for_member_access_highlighting = hint
+resharper_built_in_type_reference_style_highlighting = hint
+resharper_enforce_do_while_statement_braces_highlighting = warning
+resharper_enforce_fixed_statement_braces_highlighting = warning
+resharper_enforce_foreach_statement_braces_highlighting = warning
+resharper_enforce_for_statement_braces_highlighting = warning
+resharper_enforce_if_statement_braces_highlighting = warning
+resharper_enforce_lock_statement_braces_highlighting = warning
+resharper_enforce_using_statement_braces_highlighting = warning
+resharper_enforce_while_statement_braces_highlighting = warning
+resharper_redundant_base_qualifier_highlighting = warning
+resharper_redundant_default_member_initializer_highlighting = hint
+resharper_remove_redundant_braces_highlighting = warning
+resharper_suggest_var_or_type_built_in_types_highlighting = hint
+resharper_suggest_var_or_type_elsewhere_highlighting = hint
+resharper_suggest_var_or_type_simple_types_highlighting = hint
+resharper_unnecessary_whitespace_highlighting = warning
+resharper_use_null_propagation_when_possible_highlighting = suggestion
+resharper_web_config_module_not_resolved_highlighting = warning
+resharper_web_config_type_not_resolved_highlighting = warning
+resharper_web_config_wrong_module_highlighting = warning
+resharper_partial_type_with_single_part_highlighting = none
# .NET Analzyer settings
# VSTHRD200: Use "Async" suffix for awaitable methods
@@ -134,35 +1015,37 @@ dotnet_diagnostic.VSTHRD200.severity = none
# CA2007: Do not directly await a Task
dotnet_diagnostic.CA2007.severity = error
-[*.{cs,cshtml}]
-charset=utf-8
-indent_style=space
-indent_size=4
-insert_final_newline=true
-
-[*.{js,ts,vue}]
-indent_style=space
-indent_size=4
-insert_final_newline=true
-
-[*.{xml,yml,yaml}]
-indent_style=space
-indent_size=2
-insert_final_newline=true
-
-[*.json]
-indent_style=space
-indent_size=4
-insert_final_newline=true
-
-[*.{xml,csproj,props,targets}]
-indent_style=space
-
-[{*.har,*.inputactions,*.jsb2,*.jsb3,.babelrc,.eslintrc,.prettierrc,.stylelintrc,bowerrc,jest.config}]
-indent_style=space
-indent_size=2
-
-[*.{appxmanifest,asax,ascx,aspx,build,cg,cginc,compute,cs,cshtml,dtd,fs,fsi,fsscript,fsx,hlsl,hlsli,hlslinc,master,ml,mli,nuspec,razor,resw,resx,shader,skin,usf,ush,vb,xaml,xamlx,xoml,xsd}]
-indent_style=space
-indent_size=4
-tab_width=4
+ij_xml_align_attributes = true
+ij_xml_align_text = false
+ij_xml_attribute_wrap = normal
+ij_xml_block_comment_at_first_column = true
+ij_xml_keep_blank_lines = 2
+ij_xml_keep_indents_on_empty_lines = false
+ij_xml_keep_line_breaks = true
+ij_xml_keep_line_breaks_in_text = true
+ij_xml_keep_whitespaces = true
+ij_xml_keep_whitespaces_around_cdata = preserve
+ij_xml_keep_whitespaces_inside_cdata = false
+ij_xml_line_comment_at_first_column = true
+ij_xml_space_after_tag_name = false
+ij_xml_space_around_equals_in_attribute = false
+ij_xml_space_inside_empty_tag = true
+ij_xml_text_wrap = off
+
+# Microsoft .NET properties
+dotnet_naming_rule.unity_serialized_field_rule.import_to_resharper = True
+dotnet_naming_rule.unity_serialized_field_rule.resharper_description = Unity serialized field
+dotnet_naming_rule.unity_serialized_field_rule.resharper_guid = 5f0fdb63-c892-4d2c-9324-15c80b22a7ef
+dotnet_naming_rule.unity_serialized_field_rule.severity = warning
+dotnet_naming_rule.unity_serialized_field_rule.style = lower_camel_case_style
+dotnet_naming_rule.unity_serialized_field_rule.symbols = unity_serialized_field_symbols
+dotnet_naming_style.lower_camel_case_style.capitalization = camel_case
+dotnet_naming_symbols.unity_serialized_field_symbols.applicable_accessibilities = *
+dotnet_naming_symbols.unity_serialized_field_symbols.applicable_kinds =
+dotnet_naming_symbols.unity_serialized_field_symbols.resharper_applicable_kinds = unity_serialised_field
+dotnet_naming_symbols.unity_serialized_field_symbols.resharper_required_modifiers = instance
+
+[*.{appxmanifest,asax,ascx,aspx,axaml,build,cg,cginc,compute,dtd,fs,fsi,fsscript,fsx,hlsl,hlsli,hlslinc,master,ml,mli,nuspec,paml,resw,resx,shader,skin,usf,ush,vb,xaml,xamlx,xoml,xsd}]
+indent_style = space
+indent_size = 4
+tab_width = 4
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index e7351596b..dc540b305 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -19,17 +19,21 @@ name: ci
on:
push:
branches:
- - master
- - next
+ - 'master'
+ - 'main'
+ - 'next'
tags:
- - v*
+ - 'v*'
pull_request:
branches:
- - master
- - next
+ - 'master'
+ - 'main'
+ - 'next'
jobs:
Build:
+ env:
+ NUGET_PACKAGES: '${{ github.workspace }}/.nuget/packages'
strategy:
fail-fast: false
matrix:
@@ -44,18 +48,21 @@ jobs:
- name: Fetch all history for all tags and branches
run: |
git fetch --prune
- - name: 🔨 Use .NET Core 2.1 SDK
- uses: actions/setup-dotnet@v1.9.0
+ - name: NuGet Cache
+ uses: actions/cache@v2
with:
- dotnet-version: '2.1.x'
+ path: '${{ github.workspace }}/.nuget/packages'
+ key: "${{ runner.os }}-nuget-${{ hashFiles('**/Directory.Build.targets', '**/Directory.Build.props', '**/*.csproj') }}"
+ restore-keys: |
+ ${{ runner.os }}-nuget-
- name: 🔨 Use .NET Core 3.1 SDK
uses: actions/setup-dotnet@v1.9.0
with:
dotnet-version: '3.1.x'
- - name: 🔨 Use .NET Core 5.0 SDK
+ - name: 🔨 Use .NET Core 6.0 SDK
uses: actions/setup-dotnet@v1.9.0
with:
- dotnet-version: '5.0.x'
+ dotnet-version: '6.0.x'
- name: 🎁 dotnet tool restore
run: |
dotnet tool restore
@@ -67,7 +74,7 @@ jobs:
dotnet nuke Build --skip
- name: 🚦 Test
run: |
- dotnet nuke Test Trigger_Code_Coverage_Reports Generate_Code_Coverage_Report_Cobertura Generate_Code_Coverage_Badges Generate_Code_Coverage_Summary Generate_Code_Coverage_Report --skip
+ dotnet nuke Test TriggerCodeCoverageReports GenerateCodeCoverageReportCobertura GenerateCodeCoverageBadges GenerateCodeCoverageSummary GenerateCodeCoverageReport --skip
- name: 📦 Pack
run: |
dotnet nuke Pack --skip
@@ -78,21 +85,18 @@ jobs:
fail_ci_if_error: 'true'
- name: 🏺 Publish logs
if: always()
- continue-on-error: true
uses: actions/upload-artifact@v2
with:
name: 'logs'
path: 'artifacts/logs/'
- name: 🏺 Publish coverage data
if: always()
- continue-on-error: true
uses: actions/upload-artifact@v2
with:
name: 'coverage'
path: 'coverage/'
- name: 🏺 Publish test data
if: always()
- continue-on-error: true
uses: actions/upload-artifact@v2
with:
name: 'test data'
@@ -103,3 +107,10 @@ jobs:
with:
name: 'nuget'
path: 'artifacts/nuget/'
+ Publish:
+ needs:
+ - Build
+ secrets:
+ RSG_NUGET_API_KEY: '${{ secrets.RSG_NUGET_API_KEY }}'
+ RSG_AZURE_DEVOPS: '${{ secrets.RSG_AZURE_DEVOPS }}'
+ uses: RocketSurgeonsGuild/actions/.github/workflows/publish-nuget.yml@v0.3.0
diff --git a/.gitignore b/.gitignore
index 97caab569..f2f6f24b6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -45,3 +45,4 @@ coverage.json
coverage.info
/codealike.json
.tmp/
+.nuke/temp/
diff --git a/.husky/pre-commit b/.husky/pre-commit
new file mode 100644
index 000000000..c6d920851
--- /dev/null
+++ b/.husky/pre-commit
@@ -0,0 +1,9 @@
+#!/bin/sh
+. "$(dirname "$0")/_/husky.sh"
+
+npx lint-staged -d -r
+dotnet nuke --generate-configuration GitHubActions_ci --host GitHubActions
+git add .github/workflows/ci.yml
+dotnet nuke --generate-configuration GitHubActions_ci-ignore --host GitHubActions
+git add .github/workflows/ci-ignore.yml
+git add .nuke/build.schema.json
\ No newline at end of file
diff --git a/.huskyrc b/.huskyrc
deleted file mode 100644
index 80f5453bb..000000000
--- a/.huskyrc
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "hooks": {
- "pre-commit": "lint-staged"
- }
-}
\ No newline at end of file
diff --git a/.lintstagedrc b/.lintstagedrc
deleted file mode 100644
index 3dff2b2fb..000000000
--- a/.lintstagedrc
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "*.{cs,vb}": [
- "dotnet nuke lint --no-logo --lint-files"
- ],
- "*.{js,ts,jsx,tsx,json,yml,yaml}": [
- "prettier --write"
- ]
-}
diff --git a/.lintstagedrc.js b/.lintstagedrc.js
new file mode 100644
index 000000000..8403c0104
--- /dev/null
+++ b/.lintstagedrc.js
@@ -0,0 +1,28 @@
+function forEachChunk(chunks, callback, chunkSize = 50) {
+ var mappedFiles = [];
+ var files = chunks.concat();
+ while (files.length > 0) {
+ var chunk = files.splice(0, chunkSize);
+ mappedFiles = mappedFiles.concat(callback(chunk));
+ }
+ return mappedFiles;
+}
+
+function cleanupcode(filenames) {
+ var sln = require('./.nuke/parameters.json').Solution;
+ return forEachChunk(filenames, chunk => [
+ `dotnet jb cleanupcode ${sln} "--profile=Full Cleanup" "--disable-settings-layers=GlobalAll;GlobalPerProduct;SolutionPersonal;ProjectPersonal" "--include=${chunk.join(
+ ';'
+ )}"`,
+ ]);
+}
+
+module.exports = {
+ '*.cs': filenames => {
+ return [`echo "'${filenames.join(`' '`)}'" | dotnet format --include -`].concat(cleanupcode(filenames));
+ },
+ '*.{csproj,targets,props,xml}': filenames =>
+ forEachChunk(filenames, chunk => [`prettier --write '${chunk.join(`' '`)}'`]),
+ '*.{js,ts,jsx,tsx,json,yml,yaml}': filenames =>
+ forEachChunk(filenames, chunk => [`prettier --write '${chunk.join(`' '`)}'`]),
+};
diff --git a/.nuke b/.nuke
deleted file mode 100644
index d1bf89faf..000000000
--- a/.nuke
+++ /dev/null
@@ -1,2 +0,0 @@
-LSP.sln
-
diff --git a/.nuke/build.schema.json b/.nuke/build.schema.json
new file mode 100644
index 000000000..f99d257e6
--- /dev/null
+++ b/.nuke/build.schema.json
@@ -0,0 +1,157 @@
+{
+ "$schema": "http://json-schema.org/draft-04/schema#",
+ "title": "Build Schema",
+ "$ref": "#/definitions/build",
+ "definitions": {
+ "build": {
+ "type": "object",
+ "properties": {
+ "Artifacts": {
+ "type": "string",
+ "description": "The directory where artifacts are to be dropped"
+ },
+ "Configuration": {
+ "type": "string",
+ "description": "Configuration to build",
+ "enum": [
+ "Debug",
+ "Release"
+ ]
+ },
+ "Continue": {
+ "type": "boolean",
+ "description": "Indicates to continue a previously failed build attempt"
+ },
+ "Coverage": {
+ "type": "string",
+ "description": "The directory where coverage artifacts are to be dropped"
+ },
+ "Help": {
+ "type": "boolean",
+ "description": "Shows the help text for this build assembly"
+ },
+ "Host": {
+ "type": "string",
+ "description": "Host for execution. Default is 'automatic'",
+ "enum": [
+ "AppVeyor",
+ "AzurePipelines",
+ "Bamboo",
+ "Bitrise",
+ "GitHubActions",
+ "GitLab",
+ "Jenkins",
+ "Rider",
+ "SpaceAutomation",
+ "TeamCity",
+ "Terminal",
+ "TravisCI",
+ "VisualStudio",
+ "VSCode"
+ ]
+ },
+ "NoLogo": {
+ "type": "boolean",
+ "description": "Disables displaying the NUKE logo"
+ },
+ "Partition": {
+ "type": "string",
+ "description": "Partition to use on CI"
+ },
+ "Plan": {
+ "type": "boolean",
+ "description": "Shows the execution plan (HTML)"
+ },
+ "Profile": {
+ "type": "array",
+ "description": "Defines the profiles to load",
+ "items": {
+ "type": "string"
+ }
+ },
+ "Root": {
+ "type": "string",
+ "description": "Root directory during build execution"
+ },
+ "Skip": {
+ "type": "array",
+ "description": "List of targets to be skipped. Empty list skips all dependencies",
+ "items": {
+ "type": "string",
+ "enum": [
+ "Build",
+ "BuildVersion",
+ "Clean",
+ "CoreBuild",
+ "CorePack",
+ "CoreRestore",
+ "CoreTest",
+ "Default",
+ "DotnetToolRestore",
+ "Generate_Code_Coverage_Badges",
+ "Generate_Code_Coverage_Report",
+ "Generate_Code_Coverage_Report_Cobertura",
+ "Generate_Code_Coverage_Summary",
+ "GenerateCodeCoverageBadges",
+ "GenerateCodeCoverageReport",
+ "GenerateCodeCoverageReportCobertura",
+ "GenerateCodeCoverageSummary",
+ "GenerateReadme",
+ "Pack",
+ "Restore",
+ "Test",
+ "Trigger_Code_Coverage_Reports",
+ "TriggerCodeCoverageReports"
+ ]
+ }
+ },
+ "Solution": {
+ "type": "string",
+ "description": "Path to a solution file that is automatically loaded"
+ },
+ "Target": {
+ "type": "array",
+ "description": "List of targets to be invoked. Default is '{default_target}'",
+ "items": {
+ "type": "string",
+ "enum": [
+ "Build",
+ "BuildVersion",
+ "Clean",
+ "CoreBuild",
+ "CorePack",
+ "CoreRestore",
+ "CoreTest",
+ "Default",
+ "DotnetToolRestore",
+ "Generate_Code_Coverage_Badges",
+ "Generate_Code_Coverage_Report",
+ "Generate_Code_Coverage_Report_Cobertura",
+ "Generate_Code_Coverage_Summary",
+ "GenerateCodeCoverageBadges",
+ "GenerateCodeCoverageReport",
+ "GenerateCodeCoverageReportCobertura",
+ "GenerateCodeCoverageSummary",
+ "GenerateReadme",
+ "Pack",
+ "Restore",
+ "Test",
+ "Trigger_Code_Coverage_Reports",
+ "TriggerCodeCoverageReports"
+ ]
+ }
+ },
+ "Verbosity": {
+ "type": "string",
+ "description": "Logging verbosity during build execution. Default is 'Normal'",
+ "enum": [
+ "Minimal",
+ "Normal",
+ "Quiet",
+ "Verbose"
+ ]
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/.nuke/parameters.json b/.nuke/parameters.json
new file mode 100644
index 000000000..2d4a451b6
--- /dev/null
+++ b/.nuke/parameters.json
@@ -0,0 +1,4 @@
+{
+ "$schema": "./build.schema.json",
+ "Solution": "LSP.sln"
+}
\ No newline at end of file
diff --git a/.prettierignore b/.prettierignore
index 2faf38352..33227515d 100644
--- a/.prettierignore
+++ b/.prettierignore
@@ -1,2 +1,4 @@
azure-pipelines.nuke.yml
.github/workflows/ci.yml
+.github/workflows/ci-ignore.yml
+.nuke/build.schema.json
diff --git a/Directory.Build.props b/Directory.Build.props
index 2b19c9ec0..0eaf54839 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -28,7 +28,13 @@
true
-
+
diff --git a/Directory.Build.targets b/Directory.Build.targets
index 50e19ac9f..c40b47dd6 100644
--- a/Directory.Build.targets
+++ b/Directory.Build.targets
@@ -1,53 +1,52 @@
-
- $(BaseIntermediateOutputPath)\GeneratedFiles
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+ $(BaseIntermediateOutputPath)\GeneratedFiles
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/azure-pipelines.nuke.yml b/azure-pipelines.nuke.yml
index 633418b1c..308824ac0 100644
--- a/azure-pipelines.nuke.yml
+++ b/azure-pipelines.nuke.yml
@@ -23,7 +23,7 @@ parameters:
steps:
- pwsh: dotnet nuke Build --skip --artifacts '${{ parameters.Artifacts }}' --coverage '${{ parameters.Coverage }}' --configuration '${{ parameters.Configuration }}' --verbosity '${{ parameters.Verbosity }}'
displayName: '⚙ Build'
- - pwsh: dotnet nuke Test Trigger_Code_Coverage_Reports Generate_Code_Coverage_Report_Cobertura Generate_Code_Coverage_Badges Generate_Code_Coverage_Summary Generate_Code_Coverage_Report --skip --artifacts '${{ parameters.Artifacts }}' --coverage '${{ parameters.Coverage }}' --configuration '${{ parameters.Configuration }}' --verbosity '${{ parameters.Verbosity }}'
+ - pwsh: dotnet nuke Test TriggerCodeCoverageReports GenerateCodeCoverageReportCobertura GenerateCodeCoverageBadges GenerateCodeCoverageSummary GenerateCodeCoverageReport --skip --artifacts '${{ parameters.Artifacts }}' --coverage '${{ parameters.Coverage }}' --configuration '${{ parameters.Configuration }}' --verbosity '${{ parameters.Verbosity }}'
displayName: '🚦 Test'
- pwsh: dotnet nuke Pack --skip --artifacts '${{ parameters.Artifacts }}' --coverage '${{ parameters.Coverage }}' --configuration '${{ parameters.Configuration }}' --verbosity '${{ parameters.Verbosity }}'
displayName: '📦 Pack'
diff --git a/benchmarks/Pipeline/Pipeline.csproj b/benchmarks/Pipeline/Pipeline.csproj
index 15cca63e3..0027f64e2 100644
--- a/benchmarks/Pipeline/Pipeline.csproj
+++ b/benchmarks/Pipeline/Pipeline.csproj
@@ -9,7 +9,7 @@
-
+
diff --git a/build.cmd b/build.cmd
new file mode 100755
index 000000000..b08cc590f
--- /dev/null
+++ b/build.cmd
@@ -0,0 +1,7 @@
+:; set -eo pipefail
+:; SCRIPT_DIR=$(cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd)
+:; ${SCRIPT_DIR}/build.sh "$@"
+:; exit $?
+
+@ECHO OFF
+powershell -ExecutionPolicy ByPass -NoProfile -File "%~dp0build.ps1" %*
diff --git a/build.ps1 b/build.ps1
index 91f068d7d..9f908eb3d 100644
--- a/build.ps1
+++ b/build.ps1
@@ -4,9 +4,9 @@ Param(
[string[]]$BuildArguments
)
-Write-Output "Windows PowerShell $($Host.Version)"
+Write-Output "PowerShell $($PSVersionTable.PSEdition) version $($PSVersionTable.PSVersion)"
-Set-StrictMode -Version 2.0; $ErrorActionPreference = "Stop"; $ConfirmPreference = "None"; trap { exit 1 }
+Set-StrictMode -Version 2.0; $ErrorActionPreference = "Stop"; $ConfirmPreference = "None"; trap { Write-Error $_ -ErrorAction Continue; exit 1 }
$PSScriptRoot = Split-Path $MyInvocation.MyCommand.Path -Parent
###########################################################################
@@ -14,14 +14,15 @@ $PSScriptRoot = Split-Path $MyInvocation.MyCommand.Path -Parent
###########################################################################
$BuildProjectFile = "$PSScriptRoot\.build\.build.csproj"
-$TempDirectory = "$PSScriptRoot\\.tmp"
+$TempDirectory = "$PSScriptRoot\\.nuke\temp"
$DotNetGlobalFile = "$PSScriptRoot\\global.json"
-$DotNetInstallUrl = "https://raw.githubusercontent.com/dotnet/cli/master/scripts/obtain/dotnet-install.ps1"
+$DotNetInstallUrl = "https://dot.net/v1/dotnet-install.ps1"
$DotNetChannel = "Current"
$env:DOTNET_SKIP_FIRST_TIME_EXPERIENCE = 1
$env:DOTNET_CLI_TELEMETRY_OPTOUT = 1
+$env:DOTNET_MULTILEVEL_LOOKUP = 0
###########################################################################
# EXECUTION
@@ -32,37 +33,37 @@ function ExecSafe([scriptblock] $cmd) {
if ($LASTEXITCODE) { exit $LASTEXITCODE }
}
-# If global.json exists, load expected version
-if (Test-Path $DotNetGlobalFile) {
- $DotNetGlobal = $(Get-Content $DotNetGlobalFile | Out-String | ConvertFrom-Json)
- if ($DotNetGlobal.PSObject.Properties["sdk"] -and $DotNetGlobal.sdk.PSObject.Properties["version"]) {
- $DotNetVersion = $DotNetGlobal.sdk.version
- }
-}
-
-# If dotnet is installed locally, and expected version is not set or installation matches the expected version
-if ((Get-Command "dotnet" -ErrorAction SilentlyContinue) -ne $null -and `
- (!(Test-Path variable:DotNetVersion) -or $(& dotnet --version) -eq $DotNetVersion)) {
+# If dotnet CLI is installed globally and it matches requested version, use for execution
+if ($null -ne (Get-Command "dotnet" -ErrorAction SilentlyContinue) -and `
+ $(dotnet --version) -and $LASTEXITCODE -eq 0) {
$env:DOTNET_EXE = (Get-Command "dotnet").Path
}
else {
- $DotNetDirectory = "$TempDirectory\dotnet-win"
- $env:DOTNET_EXE = "$DotNetDirectory\dotnet.exe"
-
# Download install script
$DotNetInstallFile = "$TempDirectory\dotnet-install.ps1"
- md -force $TempDirectory > $null
+ New-Item -ItemType Directory -Path $TempDirectory -Force | Out-Null
+ [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
(New-Object System.Net.WebClient).DownloadFile($DotNetInstallUrl, $DotNetInstallFile)
+ # If global.json exists, load expected version
+ if (Test-Path $DotNetGlobalFile) {
+ $DotNetGlobal = $(Get-Content $DotNetGlobalFile | Out-String | ConvertFrom-Json)
+ if ($DotNetGlobal.PSObject.Properties["sdk"] -and $DotNetGlobal.sdk.PSObject.Properties["version"]) {
+ $DotNetVersion = $DotNetGlobal.sdk.version
+ }
+ }
+
# Install by channel or version
+ $DotNetDirectory = "$TempDirectory\dotnet-win"
if (!(Test-Path variable:DotNetVersion)) {
- ExecSafe { & $DotNetInstallFile -InstallDir $DotNetDirectory -Channel $DotNetChannel -NoPath }
+ ExecSafe { & powershell $DotNetInstallFile -InstallDir $DotNetDirectory -Channel $DotNetChannel -NoPath }
} else {
- ExecSafe { & $DotNetInstallFile -InstallDir $DotNetDirectory -Version $DotNetVersion -NoPath }
+ ExecSafe { & powershell $DotNetInstallFile -InstallDir $DotNetDirectory -Version $DotNetVersion -NoPath }
}
+ $env:DOTNET_EXE = "$DotNetDirectory\dotnet.exe"
}
Write-Output "Microsoft (R) .NET Core SDK version $(& $env:DOTNET_EXE --version)"
-ExecSafe { & $env:DOTNET_EXE build $BuildProjectFile /nodeReuse:false }
+ExecSafe { & $env:DOTNET_EXE build $BuildProjectFile /nodeReuse:false /p:UseSharedCompilation=false -nologo -clp:NoSummary --verbosity quiet }
ExecSafe { & $env:DOTNET_EXE run --project $BuildProjectFile --no-build -- $BuildArguments }
diff --git a/build.sh b/build.sh
index 25b34f4c2..75f7d9930 100755
--- a/build.sh
+++ b/build.sh
@@ -1,6 +1,6 @@
#!/usr/bin/env bash
-echo $(bash --version 2>&1 | head -n 1)
+bash --version 2>&1 | head -n 1
set -eo pipefail
SCRIPT_DIR=$(cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd)
@@ -10,53 +10,53 @@ SCRIPT_DIR=$(cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd)
###########################################################################
BUILD_PROJECT_FILE="$SCRIPT_DIR/.build/.build.csproj"
-TEMP_DIRECTORY="$SCRIPT_DIR//.tmp"
+TEMP_DIRECTORY="$SCRIPT_DIR//.nuke/temp"
DOTNET_GLOBAL_FILE="$SCRIPT_DIR//global.json"
-DOTNET_INSTALL_URL="https://raw.githubusercontent.com/dotnet/cli/master/scripts/obtain/dotnet-install.sh"
+DOTNET_INSTALL_URL="https://dot.net/v1/dotnet-install.sh"
DOTNET_CHANNEL="Current"
export DOTNET_CLI_TELEMETRY_OPTOUT=1
export DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1
+export DOTNET_MULTILEVEL_LOOKUP=0
###########################################################################
# EXECUTION
###########################################################################
function FirstJsonValue {
- perl -nle 'print $1 if m{"'$1'": "([^"\-]+)",?}' <<< ${@:2}
+ perl -nle 'print $1 if m{"'"$1"'": "([^"]+)",?}' <<< "${@:2}"
}
-# If global.json exists, load expected version
-if [ -f "$DOTNET_GLOBAL_FILE" ]; then
- DOTNET_VERSION=$(FirstJsonValue "version" $(cat "$DOTNET_GLOBAL_FILE"))
- if [ "$DOTNET_VERSION" == "" ]; then
- unset DOTNET_VERSION
- fi
-fi
-
-# If dotnet is installed locally, and expected version is not set or installation matches the expected version
-if [[ -x "$(command -v dotnet)" && (-z ${DOTNET_VERSION+x} || $(dotnet --version) == "$DOTNET_VERSION") ]]; then
+# If dotnet CLI is installed globally and it matches requested version, use for execution
+if [ -x "$(command -v dotnet)" ] && dotnet --version &>/dev/null; then
export DOTNET_EXE="$(command -v dotnet)"
else
- DOTNET_DIRECTORY="$TEMP_DIRECTORY/dotnet-unix"
- export DOTNET_EXE="$DOTNET_DIRECTORY/dotnet"
-
# Download install script
DOTNET_INSTALL_FILE="$TEMP_DIRECTORY/dotnet-install.sh"
mkdir -p "$TEMP_DIRECTORY"
curl -Lsfo "$DOTNET_INSTALL_FILE" "$DOTNET_INSTALL_URL"
chmod +x "$DOTNET_INSTALL_FILE"
+ # If global.json exists, load expected version
+ if [[ -f "$DOTNET_GLOBAL_FILE" ]]; then
+ DOTNET_VERSION=$(FirstJsonValue "version" "$(cat "$DOTNET_GLOBAL_FILE")")
+ if [[ "$DOTNET_VERSION" == "" ]]; then
+ unset DOTNET_VERSION
+ fi
+ fi
+
# Install by channel or version
- if [ -z ${DOTNET_VERSION+x} ]; then
+ DOTNET_DIRECTORY="$TEMP_DIRECTORY/dotnet-unix"
+ if [[ -z ${DOTNET_VERSION+x} ]]; then
"$DOTNET_INSTALL_FILE" --install-dir "$DOTNET_DIRECTORY" --channel "$DOTNET_CHANNEL" --no-path
else
"$DOTNET_INSTALL_FILE" --install-dir "$DOTNET_DIRECTORY" --version "$DOTNET_VERSION" --no-path
fi
+ export DOTNET_EXE="$DOTNET_DIRECTORY/dotnet"
fi
echo "Microsoft (R) .NET Core SDK version $("$DOTNET_EXE" --version)"
-"$DOTNET_EXE" build "$BUILD_PROJECT_FILE" /nodeReuse:false
+"$DOTNET_EXE" build "$BUILD_PROJECT_FILE" /nodeReuse:false /p:UseSharedCompilation=false -nologo -clp:NoSummary --verbosity quiet
"$DOTNET_EXE" run --project "$BUILD_PROJECT_FILE" --no-build -- "$@"
diff --git a/global.json b/global.json
new file mode 100644
index 000000000..403171d04
--- /dev/null
+++ b/global.json
@@ -0,0 +1,5 @@
+{
+ "sdk": {
+ "version": "6.0.200"
+ }
+}
\ No newline at end of file
diff --git a/package.json b/package.json
index 434e4b243..f731e5687 100644
--- a/package.json
+++ b/package.json
@@ -1,8 +1,12 @@
{
"private": true,
"devDependencies": {
- "husky": "^7.0.2",
- "lint-staged": "^11.1.2",
- "prettier": "^2.5.1"
+ "@prettier/plugin-xml": "1.2.0",
+ "husky": "7.0.4",
+ "lint-staged": "12.3.4",
+ "prettier": "2.5.1"
+ },
+ "scripts": {
+ "prepare": "husky install"
}
}
diff --git a/sample/SampleServer/SampleServer.csproj b/sample/SampleServer/SampleServer.csproj
index ce86be19e..2f6296f5d 100644
--- a/sample/SampleServer/SampleServer.csproj
+++ b/sample/SampleServer/SampleServer.csproj
@@ -11,8 +11,8 @@
-
-
+
+
diff --git a/src/JsonRpc.Generators/AssemblyCapabilityKeyAttributeGenerator.cs b/src/JsonRpc.Generators/AssemblyCapabilityKeyAttributeGenerator.cs
index 55dd9ae7a..538a04a54 100644
--- a/src/JsonRpc.Generators/AssemblyCapabilityKeyAttributeGenerator.cs
+++ b/src/JsonRpc.Generators/AssemblyCapabilityKeyAttributeGenerator.cs
@@ -1,113 +1,84 @@
using System.Collections.Generic;
+using System.Collections.Immutable;
using System.Linq;
using System.Text;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
-using OmniSharp.Extensions.JsonRpc.Generators.Cache;
+using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
namespace OmniSharp.Extensions.JsonRpc.Generators
{
[Generator]
- public class AssemblyCapabilityKeyAttributeGenerator : CachedSourceGenerator
+ public class AssemblyCapabilityKeyAttributeGenerator : IIncrementalGenerator
{
- protected override void Execute(
- GeneratorExecutionContext context, SyntaxReceiver syntaxReceiver, AddCacheSource addCacheSource,
- ReportCacheDiagnostic cacheDiagnostic
- )
+ public void Initialize(IncrementalGeneratorInitializationContext context)
{
- var namespaces = new HashSet() { "OmniSharp.Extensions.LanguageServer.Protocol" };
- var types = syntaxReceiver.FoundNodes
- .Concat(syntaxReceiver.Handlers)
- .Select(
- options => {
- var semanticModel = context.Compilation.GetSemanticModel(options.SyntaxTree);
- foreach (var item in options.SyntaxTree.GetCompilationUnitRoot()
- .Usings
- .Where(z => z.Alias == null)
- .Select(z => z.Name.ToFullString()))
- {
- namespaces.Add(item);
- }
-
- var typeSymbol = semanticModel.GetDeclaredSymbol(options)!;
+ var syntaxProvider = context.SyntaxProvider.CreateSyntaxProvider(
+ predicate: (syntaxNode, token) =>
+ {
+ if (syntaxNode.Parent is TypeDeclarationSyntax) return false;
+ if (syntaxNode is TypeDeclarationSyntax { Arity: 0, BaseList: { } bl } typeDeclarationSyntax
+ and (ClassDeclarationSyntax or RecordDeclarationSyntax)
+ && !typeDeclarationSyntax.Modifiers.Any(SyntaxKind.AbstractKeyword)
+ && typeDeclarationSyntax.AttributeLists.ContainsAttribute("CapabilityKey")
+ && bl.Types.Any(
+ z => z.Type switch
+ {
+ SimpleNameSyntax
+ {
+ Identifier: { Text: "ICapability" or "DynamicCapability" or "IDynamicCapability" or "LinkSupportCapability" }, Arity: 0
+ } => true,
+ _ => false
+ }
+ ))
+ {
+ return true;
+ }
- return SyntaxFactory.Attribute(
- SyntaxFactory.IdentifierName("AssemblyCapabilityKey"), SyntaxFactory.AttributeArgumentList(
- SyntaxFactory.SeparatedList(
- new[] {
- SyntaxFactory.AttributeArgument(
- SyntaxFactory.TypeOfExpression(SyntaxFactory.ParseName(typeSymbol.ToDisplayString()))
- ),
- }.Concat(options.AttributeLists.GetAttribute("CapabilityKey")!.ArgumentList!.Arguments)
- )
- )
- );
- }
- )
- .ToArray();
- if (types.Any())
- {
- var cu = SyntaxFactory.CompilationUnit()
- .WithUsings(SyntaxFactory.List(namespaces.OrderBy(z => z).Select(z => SyntaxFactory.UsingDirective(SyntaxFactory.ParseName(z)))))
- .AddAttributeLists(
- SyntaxFactory.AttributeList(
- target: SyntaxFactory.AttributeTargetSpecifier(SyntaxFactory.Token(SyntaxKind.AssemblyKeyword)), SyntaxFactory.SeparatedList(types)
- )
- )
- .WithLeadingTrivia(SyntaxFactory.Comment(Preamble.GeneratedByATool))
- .WithTrailingTrivia(SyntaxFactory.CarriageReturnLineFeed);
+ return false;
+ },
+ transform: (syntaxContext, token) =>
+ {
+ var namespaces = new HashSet() { "OmniSharp.Extensions.LanguageServer.Protocol" };
+ var tds = (TypeDeclarationSyntax)syntaxContext.Node;
+
+ foreach (var item in syntaxContext.Node.SyntaxTree.GetCompilationUnitRoot()
+ .Usings.Where(z => z.Alias == null)
+ .Select(z => z.Name.ToFullString()))
+ {
+ namespaces.Add(item);
+ }
- context.AddSource("AssemblyCapabilityKeys.cs", cu.NormalizeWhitespace().GetText(Encoding.UTF8));
- }
- }
+ var typeSymbol = syntaxContext.SemanticModel.GetDeclaredSymbol(syntaxContext.Node)!;
- public AssemblyCapabilityKeyAttributeGenerator() : base(() => new SyntaxReceiver(Cache))
- {
+ return (namespaces, Attribute(IdentifierName("AssemblyCapabilityKey"), AttributeArgumentList(SeparatedList(new[] { AttributeArgument(TypeOfExpression(ParseName(typeSymbol.ToDisplayString()))), }.Concat(tds.AttributeLists.GetAttribute("CapabilityKey")!.ArgumentList!.Arguments)))));
+ }
+ ).Collect();
+
+ context.RegisterSourceOutput(syntaxProvider, GenerateAssemblyCapabilityKeys);
}
- public static CacheContainer Cache = new();
-
- public class SyntaxReceiver : SyntaxReceiverCache
+ private void GenerateAssemblyCapabilityKeys(SourceProductionContext context, ImmutableArray<(HashSet namespaces, AttributeSyntax attribute)> types)
{
- public List Handlers { get; } = new();
-
- public override string? GetKey(TypeDeclarationSyntax syntax)
- {
- var hasher = new CacheKeyHasher();
- hasher.Append(syntax.SyntaxTree.FilePath);
- hasher.Append(syntax.Keyword.Text);
- hasher.Append(syntax.Identifier.Text);
- hasher.Append(syntax.TypeParameterList);
- hasher.Append(syntax.AttributeLists);
- hasher.Append(syntax.BaseList);
-
- return hasher;
- }
-
- ///
- /// Called for every syntax node in the compilation, we can inspect the nodes and save any information useful for generation
- ///
- public override void OnVisitNode(TypeDeclarationSyntax syntaxNode)
- {
- if (syntaxNode.Parent is TypeDeclarationSyntax) return;
- if (syntaxNode is ClassDeclarationSyntax or RecordDeclarationSyntax
- && syntaxNode.Arity == 0
- && !syntaxNode.Modifiers.Any(SyntaxKind.AbstractKeyword)
- && syntaxNode.AttributeLists.ContainsAttribute("CapabilityKey")
- && syntaxNode.BaseList is { } bl && bl.Types.Any(
- z => z.Type switch {
- SimpleNameSyntax { Identifier: { Text: "ICapability" or "DynamicCapability" or "IDynamicCapability" or "LinkSupportCapability" }, Arity: 0 } => true,
- _ => false
- }
- ))
+ var namespaces = types.Aggregate(
+ new HashSet(), (set, tuple) =>
{
- Handlers.Add(syntaxNode);
- }
- }
+ foreach (var name in tuple.namespaces)
+ {
+ set.Add(name);
+ }
- public SyntaxReceiver(CacheContainer cache) : base(cache)
+ return set;
+ }
+ );
+ if (types.Any())
{
+ var cu = CompilationUnit()
+ .WithUsings(List(namespaces.OrderBy(z => z).Select(z => UsingDirective(ParseName(z)))))
+ .AddAttributeLists(AttributeList(target: AttributeTargetSpecifier(Token(SyntaxKind.AssemblyKeyword)), SeparatedList(types.Select(z => z.attribute))));
+
+ context.AddSource("AssemblyCapabilityKeys.cs", cu.NormalizeWhitespace().GetText(Encoding.UTF8));
}
}
}
diff --git a/src/JsonRpc.Generators/AssemblyJsonRpcHandlersAttributeGenerator.cs b/src/JsonRpc.Generators/AssemblyJsonRpcHandlersAttributeGenerator.cs
index 81b6f97df..9871cd1bb 100644
--- a/src/JsonRpc.Generators/AssemblyJsonRpcHandlersAttributeGenerator.cs
+++ b/src/JsonRpc.Generators/AssemblyJsonRpcHandlersAttributeGenerator.cs
@@ -1,122 +1,89 @@
using System;
using System.Collections.Generic;
+using System.Collections.Immutable;
using System.Diagnostics;
using System.Linq;
using System.Text;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
-using OmniSharp.Extensions.JsonRpc.Generators.Cache;
-using OmniSharp.Extensions.JsonRpc.Generators.Contexts;
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
namespace OmniSharp.Extensions.JsonRpc.Generators
{
[Generator]
- public class AssemblyJsonRpcHandlersAttributeGenerator : CachedSourceGenerator
+ public class AssemblyJsonRpcHandlersAttributeGenerator : IIncrementalGenerator
{
- protected override void Execute(
- GeneratorExecutionContext context, SyntaxReceiver syntaxReceiver, AddCacheSource addCacheSource,
- ReportCacheDiagnostic cacheDiagnostic
- )
+ public void Initialize(IncrementalGeneratorInitializationContext context)
{
- var namespaces = new HashSet() { "OmniSharp.Extensions.JsonRpc" };
- var types = syntaxReceiver.FoundNodes
- .Concat(syntaxReceiver.Handlers)
- .Select(
- options => {
- var semanticModel = context.Compilation.GetSemanticModel(options.SyntaxTree);
- var typeSymbol = semanticModel.GetDeclaredSymbol(options)!;
+ var syntaxProvider = context
+ .SyntaxProvider
+ .CreateSyntaxProvider(
+ predicate: (syntaxNode, token) =>
+ {
+ if (syntaxNode.Parent is TypeDeclarationSyntax) return false;
+ if (syntaxNode is TypeDeclarationSyntax { Arity: 0, BaseList: { } bl } typeDeclarationSyntax
+ and (ClassDeclarationSyntax or RecordDeclarationSyntax)
+ && !typeDeclarationSyntax.Modifiers.Any(SyntaxKind.AbstractKeyword)
+ && typeDeclarationSyntax.AttributeLists.ContainsAttribute("Method")
+ && bl.Types.Any(
+ z => z.Type switch
+ {
+ SimpleNameSyntax { Identifier: { Text: "IJsonRpcNotificationHandler" }, Arity: 0 or 1 } => true,
+ SimpleNameSyntax { Identifier: { Text: "ICanBeResolvedHandler" }, Arity: 1 } => true,
+ SimpleNameSyntax { Identifier: { Text: "IJsonRpcRequestHandler" }, Arity: 1 or 2 } => true,
+ SimpleNameSyntax { Identifier: { Text: "IJsonRpcHandler" }, Arity: 0 } => true,
+ _ => false
+ }
+ ))
+ {
+ return true;
+ }
- return AttributeArgument(TypeOfExpression(ParseName(typeSymbol.ToDisplayString())));
- }
- )
- .ToArray();
- if (types.Any())
- {
- var cu = CompilationUnit()
- .WithUsings(List(namespaces.OrderBy(z => z).Select(z => UsingDirective(ParseName(z)))))
- .WithLeadingTrivia(Comment(Preamble.GeneratedByATool))
- .WithTrailingTrivia(CarriageReturnLineFeed);
- while (types.Length > 0)
- {
- var innerTypes = types.Take(10).ToArray();
- types = types.Skip(10).ToArray();
- cu = cu.AddAttributeLists(
- AttributeList(
- target: AttributeTargetSpecifier(Token(SyntaxKind.AssemblyKeyword)),
- SingletonSeparatedList(Attribute(IdentifierName("AssemblyJsonRpcHandlers"), AttributeArgumentList(SeparatedList(innerTypes))))
- )
- );
- }
- context.AddSource("AssemblyJsonRpcHandlers.cs", cu.NormalizeWhitespace().GetText(Encoding.UTF8));
- }
- }
+ if (syntaxNode is InterfaceDeclarationSyntax { Arity: 0, BaseList: { } bl2 } interfaceDeclarationSyntax
+ && interfaceDeclarationSyntax.AttributeLists.ContainsAttribute("Method")
+ && bl2.Types.Any(
+ z => z.Type switch
+ {
+ SimpleNameSyntax { Identifier: { Text: "IJsonRpcNotificationHandler" }, Arity: 0 or 1 } => true,
+ SimpleNameSyntax { Identifier: { Text: "ICanBeResolvedHandler" }, Arity: 1 } => true,
+ SimpleNameSyntax { Identifier: { Text: "IJsonRpcRequestHandler" }, Arity: 1 or 2 } => true,
+ SimpleNameSyntax { Identifier: { Text: "IJsonRpcHandler" }, Arity: 0 } => true,
+ _ => false
+ }
+ ))
+ {
+ return true;
+ }
- public AssemblyJsonRpcHandlersAttributeGenerator() : base(() => new SyntaxReceiver(Cache))
- {
- }
+ return false;
+ },
+ transform: (syntaxContext, token) => AttributeArgument(
+ TypeOfExpression(
+ ParseName(syntaxContext.SemanticModel.GetDeclaredSymbol(syntaxContext.Node)!.ToDisplayString())
+ )
+ )
+ )
+ .Collect();
- public static CacheContainer Cache = new();
+ context.RegisterSourceOutput(syntaxProvider, GenerateAssemblyJsonRpcHandlers);
+ }
- public class SyntaxReceiver : SyntaxReceiverCache
+ private void GenerateAssemblyJsonRpcHandlers(SourceProductionContext context, ImmutableArray types)
{
- public List Handlers { get; } = new();
-
- public override string? GetKey(TypeDeclarationSyntax syntax)
- {
- var hasher = new CacheKeyHasher();
- hasher.Append(syntax.SyntaxTree.FilePath);
- hasher.Append(syntax.Keyword.Text);
- hasher.Append(syntax.Identifier.Text);
- hasher.Append(syntax.TypeParameterList);
- hasher.Append(syntax.AttributeLists);
- hasher.Append(syntax.BaseList);
- return hasher;
- }
-
- ///
- /// Called for every syntax node in the compilation, we can inspect the nodes and save any information useful for generation
- ///
- public override void OnVisitNode(TypeDeclarationSyntax syntaxNode)
+ var namespaces = new HashSet() { "OmniSharp.Extensions.JsonRpc" };
+ if (types.Any())
{
- if (syntaxNode.Parent is TypeDeclarationSyntax) return;
- if (syntaxNode is ClassDeclarationSyntax or RecordDeclarationSyntax
- && syntaxNode.Arity == 0
- && !syntaxNode.Modifiers.Any(SyntaxKind.AbstractKeyword)
- && syntaxNode.AttributeLists.ContainsAttribute("Method")
- && syntaxNode.BaseList is { } bl && bl.Types.Any(
- z => z.Type switch {
- SimpleNameSyntax { Identifier: { Text: "IJsonRpcNotificationHandler" }, Arity: 0 or 1 } => true,
- SimpleNameSyntax { Identifier: { Text: "ICanBeResolvedHandler" }, Arity: 1 } => true,
- SimpleNameSyntax { Identifier: { Text: "IJsonRpcRequestHandler" }, Arity: 1 or 2 } => true,
- SimpleNameSyntax { Identifier: { Text: "IJsonRpcHandler" }, Arity: 0 } => true,
- _ => false
- }
- ))
- {
- Handlers.Add(syntaxNode);
- }
-
- if (syntaxNode is InterfaceDeclarationSyntax
- && syntaxNode.Arity == 0
- && syntaxNode.AttributeLists.ContainsAttribute("Method")
- && syntaxNode.BaseList is { } bl2 && bl2.Types.Any(
- z => z.Type switch {
- SimpleNameSyntax { Identifier: { Text: "IJsonRpcNotificationHandler" }, Arity: 0 or 1 } => true,
- SimpleNameSyntax { Identifier: { Text: "ICanBeResolvedHandler" }, Arity: 1 } => true,
- SimpleNameSyntax { Identifier: { Text: "IJsonRpcRequestHandler" }, Arity: 1 or 2 } => true,
- SimpleNameSyntax { Identifier: { Text: "IJsonRpcHandler" }, Arity: 0 } => true,
- _ => false
- }
- ))
+ var cu = CompilationUnit()
+ .WithUsings(List(namespaces.OrderBy(z => z).Select(z => UsingDirective(ParseName(z)))));
+ while (types.Length > 0)
{
- Handlers.Add(syntaxNode);
+ var innerTypes = types.Take(10).ToArray();
+ types = types.Skip(10).ToImmutableArray();
+ cu = cu.AddAttributeLists(AttributeList(target: AttributeTargetSpecifier(Token(SyntaxKind.AssemblyKeyword)), SingletonSeparatedList(Attribute(IdentifierName("AssemblyJsonRpcHandlers"), AttributeArgumentList(SeparatedList(innerTypes))))));
}
- }
- public SyntaxReceiver(CacheContainer cache) : base(cache)
- {
+ context.AddSource("AssemblyJsonRpcHandlers.cs", cu.NormalizeWhitespace().GetText(Encoding.UTF8));
}
}
}
diff --git a/src/JsonRpc.Generators/AutoImplementParamsGenerator.cs b/src/JsonRpc.Generators/AutoImplementParamsGenerator.cs
index 541aa1c2b..74287848d 100644
--- a/src/JsonRpc.Generators/AutoImplementParamsGenerator.cs
+++ b/src/JsonRpc.Generators/AutoImplementParamsGenerator.cs
@@ -1,3 +1,4 @@
+using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
@@ -5,69 +6,84 @@
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
-using OmniSharp.Extensions.JsonRpc.Generators.Cache;
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
using static OmniSharp.Extensions.JsonRpc.Generators.CommonElements;
namespace OmniSharp.Extensions.JsonRpc.Generators
{
[Generator]
- public class AutoImplementParamsGenerator : CachedSourceGenerator
+ public class AutoImplementParamsGenerator : IIncrementalGenerator
{
- protected override void Execute(
- GeneratorExecutionContext context, SyntaxReceiver syntaxReceiver, AddCacheSource addCacheSource,
- ReportCacheDiagnostic cacheDiagnostic
- )
+ public void Initialize(IncrementalGeneratorInitializationContext context)
{
- foreach (var candidate in syntaxReceiver.Candidates)
- {
- var members = new List();
- var model = context.Compilation.GetSemanticModel(candidate.SyntaxTree);
- var symbol = model.GetDeclaredSymbol(candidate);
- if (symbol is null) continue;
+ var _attributes = "Method,RegistrationOptions";
+ var _interfaces = "IPartialItemsRequest,IPartialItemRequest,IWorkDoneProgressParams,IHandlerIdentity";
- var autoImplementProperties = AutoImplementInterfaces(candidate, symbol).ToArray();
- if (autoImplementProperties is { Length: > 0 })
+ var syntaxProvider = context.SyntaxProvider.CreateSyntaxProvider(
+ predicate: (syntaxNode, token) =>
{
- var extendedParams = candidate
- .WithAttributeLists(List())
- .WithMembers(List(autoImplementProperties))
- .WithConstraintClauses(List())
- .WithBaseList(null);
- members.Add(extendedParams);
- }
+ if (syntaxNode is TypeDeclarationSyntax typeDeclarationSyntax and (ClassDeclarationSyntax or RecordDeclarationSyntax)
+ && ( typeDeclarationSyntax.AttributeLists.ContainsAttribute(_attributes)
+ || typeDeclarationSyntax.BaseList?.Types.Any(type => type.Type.GetSyntaxName() is { } n && _interfaces.Contains(n)) == true
+ )
+ )
+ {
+ return true;
+ }
- if (members.Count == 0) continue;
+ return false;
+ }, transform: (syntaxContext, token) => { return syntaxContext; }
+ );
- if (!candidate.Modifiers.Any(z => z.IsKind(SyntaxKind.PartialKeyword)))
- {
- cacheDiagnostic(candidate, static c => Diagnostic.Create(GeneratorDiagnostics.MustBePartial, c.Identifier.GetLocation(), c.Identifier.Text));
- }
- var cu = CompilationUnit(
- List(),
- List(candidate.SyntaxTree.GetCompilationUnitRoot().Usings),
- List(),
- SingletonList(
- NamespaceDeclaration(ParseName(symbol.ContainingNamespace.ToDisplayString()))
- .WithMembers(List(members))
- )
- )
- .AddUsings(UsingDirective(ParseName("OmniSharp.Extensions.LanguageServer.Protocol.Serialization")))
- .WithLeadingTrivia()
- .WithTrailingTrivia()
- .WithLeadingTrivia(Comment(Preamble.GeneratedByATool), Trivia(NullableDirectiveTrivia(Token(SyntaxKind.EnableKeyword), true)))
- .WithTrailingTrivia(Trivia(NullableDirectiveTrivia(Token(SyntaxKind.RestoreKeyword), true)), CarriageReturnLineFeed);
+ context.RegisterSourceOutput(syntaxProvider, GenerateAutoImplementedInterfaces);
+ }
- addCacheSource(
- $"{Path.GetFileNameWithoutExtension(candidate.SyntaxTree.FilePath)}_{candidate.Identifier.Text}{( candidate.Arity > 0 ? candidate.Arity.ToString() : "" )}.cs",
- candidate,
- cu.NormalizeWhitespace().GetText(Encoding.UTF8)
- );
+ private static void GenerateAutoImplementedInterfaces(SourceProductionContext context, GeneratorSyntaxContext syntaxContext)
+ {
+ var candidate = (TypeDeclarationSyntax)syntaxContext.Node;
+ var members = new List();
+ var model = syntaxContext.SemanticModel;
+ var symbol = model.GetDeclaredSymbol(candidate);
+ if (symbol is null) return;
+
+ var autoImplementProperties = AutoImplementInterfaces(candidate, symbol).ToArray();
+ if (autoImplementProperties is { Length: > 0 })
+ {
+ var extendedParams = candidate.WithAttributeLists(List())
+ .WithMembers(List(autoImplementProperties))
+ .WithConstraintClauses(List())
+ .WithBaseList(null);
+ members.Add(extendedParams);
}
+
+ if (members.Count == 0) return;
+
+ if (!candidate.Modifiers.Any(z => z.IsKind(SyntaxKind.PartialKeyword)))
+ {
+ context.ReportDiagnostic(Diagnostic.Create(GeneratorDiagnostics.MustBePartial, candidate.Identifier.GetLocation(), candidate.Identifier.Text));
+ }
+
+ var cu = CompilationUnit(
+ List(), List(candidate.SyntaxTree.GetCompilationUnitRoot().Usings), List(),
+ SingletonList(
+ NamespaceDeclaration(ParseName(symbol.ContainingNamespace.ToDisplayString()))
+ .WithMembers(List(members))
+ )
+ )
+ .AddUsings(UsingDirective(ParseName("OmniSharp.Extensions.LanguageServer.Protocol.Serialization")))
+ .WithLeadingTrivia()
+ .WithTrailingTrivia()
+ .WithLeadingTrivia(Trivia(NullableDirectiveTrivia(Token(SyntaxKind.EnableKeyword), true)))
+ .WithTrailingTrivia(Trivia(NullableDirectiveTrivia(Token(SyntaxKind.RestoreKeyword), true)));
+
+ context.AddSource(
+ $"{Path.GetFileNameWithoutExtension(candidate.SyntaxTree.FilePath)}_{candidate.Identifier.Text}{( candidate.Arity > 0 ? candidate.Arity.ToString() : "" )}.cs",
+ cu.NormalizeWhitespace().GetText(Encoding.UTF8)
+ );
}
- private static IEnumerable AutoImplementInterfaces(TypeDeclarationSyntax syntax, INamedTypeSymbol symbol)
+ private static IEnumerable AutoImplementInterfaces(BaseTypeDeclarationSyntax syntax, INamedTypeSymbol symbol)
{
if (syntax.BaseList?.Types.Any(z => z.Type.GetSyntaxName() is "IWorkDoneProgressParams") == true
&& symbol.GetMembers("WorkDoneToken").IsEmpty)
@@ -93,19 +109,27 @@ private static IEnumerable AutoImplementInterfaces(Type
yield return PropertyDeclaration(PredefinedType(Token(SyntaxKind.StringKeyword)), Identifier("__identity"))
.WithAttributeLists(
List(
- new[] {
+ new[]
+ {
AttributeList(
SeparatedList(
- new[] {
+ new[]
+ {
Attribute(IdentifierName("JsonProperty"))
.WithArgumentList(
AttributeArgumentList(
SeparatedList(
- new[] {
- AttributeArgument(LiteralExpression(SyntaxKind.StringLiteralExpression, Literal("$$__handler_id__$$"))),
+ new[]
+ {
+ AttributeArgument(
+ LiteralExpression(
+ SyntaxKind.StringLiteralExpression, Literal("$$__handler_id__$$")
+ )
+ ),
AttributeArgument(
MemberAccessExpression(
- SyntaxKind.SimpleMemberAccessExpression, IdentifierName("DefaultValueHandling"),
+ SyntaxKind.SimpleMemberAccessExpression,
+ IdentifierName("DefaultValueHandling"),
IdentifierName("Ignore")
)
)
@@ -137,57 +161,5 @@ private static IEnumerable AutoImplementInterfaces(Type
.WithAccessorList(GetInitAccessor);
}
}
-
- public AutoImplementParamsGenerator() : base(() => new SyntaxReceiver(Cache))
- {
- }
-
- public static CacheContainer Cache = new();
-
- public class SyntaxReceiver : SyntaxReceiverCache
- {
- private readonly string _attributes;
- private readonly string _interfaces;
- public List Candidates { get; } = new();
-
- public SyntaxReceiver(CacheContainer cacheContainer) : base(cacheContainer)
- {
- _attributes = "Method,RegistrationOptions";
- _interfaces = "IPartialItemsRequest,IPartialItemRequest,IWorkDoneProgressParams,IHandlerIdentity";
- }
-
- public override string? GetKey(TypeDeclarationSyntax syntax)
- {
- var hasher = new CacheKeyHasher();
- hasher.Append(syntax.SyntaxTree.FilePath);
- hasher.Append(syntax.Keyword.Text);
- hasher.Append(syntax.Identifier.Text);
- hasher.Append(syntax.TypeParameterList);
- hasher.Append(syntax.AttributeLists);
- hasher.Append(syntax.BaseList);
- foreach (var item in syntax.Members.OfType().Select(z => z.Identifier.Text))
- {
- hasher.Append(item);
- }
-
- return hasher;
- }
-
- ///
- /// Called for every syntax node in the compilation, we can inspect the nodes and save any information useful for generation
- ///
- public override void OnVisitNode(TypeDeclarationSyntax syntaxNode)
- {
- // any field with at least one attribute is a candidate for property generation
- if (syntaxNode is ClassDeclarationSyntax or RecordDeclarationSyntax
- && ( syntaxNode.AttributeLists.ContainsAttribute(_attributes)
- || syntaxNode.BaseList?.Types.Any(type => type.Type.GetSyntaxName() is { } n && _interfaces.Contains(n)) == true
- )
- )
- {
- Candidates.Add(syntaxNode);
- }
- }
- }
}
}
diff --git a/src/JsonRpc.Generators/Cache/AddCacheSource.cs b/src/JsonRpc.Generators/Cache/AddCacheSource.cs
deleted file mode 100644
index e593a0c81..000000000
--- a/src/JsonRpc.Generators/Cache/AddCacheSource.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-using Microsoft.CodeAnalysis;
-using Microsoft.CodeAnalysis.Text;
-
-namespace OmniSharp.Extensions.JsonRpc.Generators.Cache
-{
- public delegate void AddCacheSource(string hintName, T syntaxNode, SourceText sourceText) where T : SyntaxNode;
-
- public delegate void ReportCacheDiagnostic(T syntaxNode, CacheDiagnosticFactory diagnostic) where T : SyntaxNode;
-
- public delegate Diagnostic CacheDiagnosticFactory(T syntaxNode) where T : SyntaxNode;
-
- public delegate Location LocationFactory(T syntaxNode) where T : SyntaxNode;
-}
diff --git a/src/JsonRpc.Generators/Cache/CacheContainer.cs b/src/JsonRpc.Generators/Cache/CacheContainer.cs
deleted file mode 100644
index 7b8084630..000000000
--- a/src/JsonRpc.Generators/Cache/CacheContainer.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-using System.Collections.Immutable;
-using System.Threading;
-using Microsoft.CodeAnalysis;
-
-namespace OmniSharp.Extensions.JsonRpc.Generators.Cache
-{
- public class CacheContainer where T : SyntaxNode
- {
- private ImmutableDictionary> _sourceTexts;
- private ImmutableDictionary>> _cacheDiagnostics;
-
- public CacheContainer()
- {
- _sourceTexts = ImmutableDictionary>.Empty;
- _cacheDiagnostics = ImmutableDictionary>>.Empty;
- }
-
- public ImmutableDictionary> SourceTexts => _sourceTexts;
- public ImmutableDictionary>> Diagnostics => _cacheDiagnostics;
-
- public void Swap(
- ImmutableDictionary.Builder sources)>.Builder foundCache,
- ImmutableDictionary>.Builder>.Builder diagnosticFactories
- )
- {
- Interlocked.Exchange(
- ref _sourceTexts,
- foundCache.ToImmutableDictionary(z => z.Key, z => z.Value.sources.ToImmutable())
- );
- Interlocked.Exchange(
- ref _cacheDiagnostics,
- diagnosticFactories.ToImmutableDictionary(z => z.Key, z => z.Value.ToImmutable())
- );
- }
- }
-}
diff --git a/src/JsonRpc.Generators/Cache/CacheKeyHasher.cs b/src/JsonRpc.Generators/Cache/CacheKeyHasher.cs
deleted file mode 100644
index 2061cbbee..000000000
--- a/src/JsonRpc.Generators/Cache/CacheKeyHasher.cs
+++ /dev/null
@@ -1,134 +0,0 @@
-using System;
-using System.Linq;
-using System.Security.Cryptography;
-using System.Text;
-using Microsoft.CodeAnalysis;
-using Microsoft.CodeAnalysis.CSharp.Syntax;
-
-namespace OmniSharp.Extensions.JsonRpc.Generators.Cache
-{
- class CacheKeyHasher : IDisposable
- {
- public static bool Cache = true;
- private readonly SHA1 _hasher;
-
- public CacheKeyHasher()
- {
- _hasher = SHA1.Create();
- }
-
- public void Append(string textToHash)
- {
- var inputBuffer = Encoding.UTF8.GetBytes(textToHash);
- _hasher.TransformBlock(inputBuffer, 0, inputBuffer.Length, inputBuffer, 0);
- }
-
- public void Append(TypeSyntax? typeSyntax)
- {
- if (typeSyntax?.GetSyntaxName() is { } a)
- {
- Append(a);
- }
-
- if (typeSyntax is GenericNameSyntax gns)
- {
- foreach (var item in gns.TypeArgumentList.Arguments)
- {
- Append(item);
- }
- }
- }
-
- public void Append(TypeParameterListSyntax? typeParameterListSyntax)
- {
- if (typeParameterListSyntax is null or { Parameters: { Count: 0 } }) return;
- foreach (var item in typeParameterListSyntax.Parameters)
- {
- Append(item.Identifier.Text);
- Append(item.AttributeLists);
- }
- }
-
- public void Append(BaseListSyntax? baseListSyntax)
- {
- if (baseListSyntax is null) return;
- foreach (var item in baseListSyntax.Types)
- {
- Append(item.Type);
- }
- }
-
- public void Append(SyntaxList attributeList)
- {
- foreach (var item in attributeList)
- {
- Append(item);
- }
- }
-
- public void Append(SyntaxList items)
- where T : MemberDeclarationSyntax
- {
- if (items is { Count: 0 }) return;
- foreach (var item in items.OfType())
- {
- Append(item.AttributeLists);
- if (item is PropertyDeclarationSyntax p)
- {
- Append(p.Identifier.Text);
- Append(p.Type);
- }
- }
- }
-
- public void Append(AttributeListSyntax attributeList)
- {
- if (attributeList is { Attributes: { Count: 0 } }) return;
- foreach (var item in attributeList.Attributes)
- {
- Append(item);
- }
- }
-
- public void Append(AttributeSyntax attribute)
- {
- Append(attribute.Name.GetSyntaxName() ?? string.Empty);
- if (attribute.ArgumentList?.Arguments is { Count: > 0 } arguments)
- {
- foreach (var item in arguments)
- {
- if (item.NameEquals is { })
- {
- Append(item.NameEquals.Name.GetSyntaxName() ?? string.Empty);
- }
-
- Append(
- item switch {
- { Expression: TypeOfExpressionSyntax tyof } => tyof.Type.GetSyntaxName() is { Length: > 0 } name ? name : string.Empty,
- { Expression: LiteralExpressionSyntax { } literal } => literal.Token.Text,
- _ => string.Empty
- }
- );
- }
- }
- }
-
- private string ConvertByteArrayToString()
- {
- _hasher.TransformFinalBlock(Array.Empty(), 0, 0);
- var sb = new StringBuilder();
- foreach (var b in _hasher.Hash)
- {
- sb.Append(b.ToString("X2"));
- }
-
- return sb.ToString();
- }
-
- public override string ToString() => ConvertByteArrayToString();
-
- public static implicit operator string(CacheKeyHasher value) => value.ToString();
-
- public void Dispose() => _hasher.Dispose();
- }
-}
diff --git a/src/JsonRpc.Generators/Cache/CachedSourceGenerator.cs b/src/JsonRpc.Generators/Cache/CachedSourceGenerator.cs
deleted file mode 100644
index 1f1cd0c42..000000000
--- a/src/JsonRpc.Generators/Cache/CachedSourceGenerator.cs
+++ /dev/null
@@ -1,66 +0,0 @@
-using System;
-using Microsoft.CodeAnalysis;
-
-namespace OmniSharp.Extensions.JsonRpc.Generators.Cache
-{
- ///
- /// We're not supposed to do this... but in realistic.
- ///
- public abstract class CachedSourceGenerator : ISourceGenerator
- where T : ISyntaxReceiver, IReceiverCache
- where TSyntax : SyntaxNode
- {
- private readonly Func _syntaxReceiverFactory;
-
- public CachedSourceGenerator(Func syntaxReceiverFactory)
- {
- _syntaxReceiverFactory = syntaxReceiverFactory;
- }
-
- public void Initialize(GeneratorInitializationContext context)
- {
- context.RegisterForSyntaxNotifications(() => _syntaxReceiverFactory());
- }
-
- public void Execute(GeneratorExecutionContext context)
- {
- if (!( context.SyntaxReceiver is T syntaxReceiver )) return;
-
- syntaxReceiver.Start(context);
- Execute(
- context, syntaxReceiver,
- (name, node, text) => {
- context.AddSource(name, text);
-
- if (CacheKeyHasher.Cache)
- {
- syntaxReceiver.AddCacheSource(name, node, text);
- }
- },
- (node, diagnostic) => {
- context.ReportDiagnostic(diagnostic(node));
-
- if (CacheKeyHasher.Cache)
- {
- syntaxReceiver.ReportCacheDiagnostic(node, diagnostic);
- }
- }
- );
- foreach (var item in syntaxReceiver.CachedSources)
- {
- context.AddSource(item.Name, item.SourceText);
- }
-
- foreach (var item in syntaxReceiver.CachedDiagnostics)
- {
- context.ReportDiagnostic(item);
- }
-
- syntaxReceiver.Finish(context);
- }
-
- protected abstract void Execute(
- GeneratorExecutionContext context, T syntaxReceiver, AddCacheSource addCacheSource, ReportCacheDiagnostic cacheDiagnostic
- );
- }
-}
diff --git a/src/JsonRpc.Generators/Cache/IReceiverCache.cs b/src/JsonRpc.Generators/Cache/IReceiverCache.cs
deleted file mode 100644
index d1e72827e..000000000
--- a/src/JsonRpc.Generators/Cache/IReceiverCache.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-using System.Collections.Generic;
-using Microsoft.CodeAnalysis;
-using Microsoft.CodeAnalysis.Text;
-
-namespace OmniSharp.Extensions.JsonRpc.Generators.Cache
-{
- public interface IReceiverCache
- where T : SyntaxNode
- {
- string? GetKey(T syntax);
- void Start(GeneratorExecutionContext context);
- void Finish(GeneratorExecutionContext context);
- IEnumerable CachedSources { get; }
- IEnumerable CachedDiagnostics { get; }
- void AddCacheSource(string hintName, T syntaxNode, SourceText sourceText);
- void ReportCacheDiagnostic(T syntaxNode, CacheDiagnosticFactory diagnostic);
- }
-}
diff --git a/src/JsonRpc.Generators/Cache/SourceTextCache.cs b/src/JsonRpc.Generators/Cache/SourceTextCache.cs
deleted file mode 100644
index 6abdd658f..000000000
--- a/src/JsonRpc.Generators/Cache/SourceTextCache.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-using System.Collections.Immutable;
-using Microsoft.CodeAnalysis;
-using Microsoft.CodeAnalysis.Text;
-
-namespace OmniSharp.Extensions.JsonRpc.Generators.Cache
-{
- public record SourceTextCache(string Name, SourceText SourceText);
- public record DiagnosticCache(ImmutableArray> Diagnostics) where T : SyntaxNode;
-}
diff --git a/src/JsonRpc.Generators/Cache/SyntaxReceiverCache.cs b/src/JsonRpc.Generators/Cache/SyntaxReceiverCache.cs
deleted file mode 100644
index 5620f5b6b..000000000
--- a/src/JsonRpc.Generators/Cache/SyntaxReceiverCache.cs
+++ /dev/null
@@ -1,125 +0,0 @@
-using System.Collections.Generic;
-using System.Collections.Immutable;
-using System.Linq;
-using Microsoft.CodeAnalysis;
-using Microsoft.CodeAnalysis.Text;
-
-namespace OmniSharp.Extensions.JsonRpc.Generators.Cache
-{
- public abstract class SyntaxReceiverCache : IReceiverCache, ISyntaxReceiver
- where T : SyntaxNode
- {
- private readonly CacheContainer _cache;
- private readonly ImmutableDictionary.Builder sources)>.Builder _foundSourceTexts;
- private readonly ImmutableDictionary>.Builder>.Builder _foundDiagnosticFactories;
- private readonly List _cachedSources = new();
- private readonly List _cachedDiagnostics = new();
- private readonly List _foundNodes = new();
-
- protected SyntaxReceiverCache(CacheContainer cache)
- {
- _cache = cache;
- _foundSourceTexts = ImmutableDictionary.Builder sources)>.Empty.ToBuilder();
- _foundDiagnosticFactories = ImmutableDictionary>.Builder>.Empty.ToBuilder();
- }
-
- public abstract string? GetKey(T syntax);
-
- public void Start(GeneratorExecutionContext context)
- {
- // TODO: Check if options disable cache
- try
- {
- // check stuff
- _cache.Swap(_foundSourceTexts, _foundDiagnosticFactories);
- }
- catch
- {
- _cachedSources.Clear();
- _cachedDiagnostics.Clear();
- foreach (var found in _foundSourceTexts.Values)
- {
- OnVisitNode(found.Item1);
- }
- }
- }
-
- public void Finish(GeneratorExecutionContext context)
- {
- // TODO: Check if options disable cache
- try
- {
- // check stuff
- _cache.Swap(_foundSourceTexts, _foundDiagnosticFactories);
- }
- catch
- {
- _cache.Swap(
- ImmutableDictionary.Builder sources)>.Empty.ToBuilder(),
- ImmutableDictionary>.Builder>.Empty.ToBuilder()
- );
- }
- }
-
- public IEnumerable CachedSources => _cachedSources;
- public IEnumerable CachedDiagnostics => _cachedDiagnostics;
- public IEnumerable FoundNodes => _foundNodes;
-
- public void OnVisitSyntaxNode(SyntaxNode syntaxNode)
- {
- if (syntaxNode is not T v) return;
- if (GetKey(v) is { } key)
- {
- if (_cache.SourceTexts.TryGetValue(key, out var cacheValue))
- {
- _foundSourceTexts.Add(key, ( v, cacheValue.ToBuilder() ));
- _cachedSources.AddRange(cacheValue);
- }
-
- if (_cache.Diagnostics.TryGetValue(key, out var diagnostics))
- {
- _foundDiagnosticFactories.Add(key, diagnostics.ToBuilder());
- _cachedDiagnostics.AddRange(diagnostics.Select(f => f(v)));
- }
-
- if (_foundSourceTexts.ContainsKey(key) || _foundDiagnosticFactories.ContainsKey(key))
- {
- _foundNodes.Add(v);
- return;
- }
- }
-
- OnVisitNode(v);
- }
-
- public void AddCacheSource(string hintName, T syntaxNode, SourceText sourceText)
- {
- if (GetKey(syntaxNode) is not { } key) return;
- if (!_foundSourceTexts.TryGetValue(key, out var data))
- {
- var array = ImmutableArray.Create(new SourceTextCache(hintName, sourceText)).ToBuilder();
- _foundSourceTexts.Add(key, ( syntaxNode, array ));
- }
- else
- {
- data.sources.Add(new SourceTextCache(hintName, sourceText));
- }
- }
-
- public void ReportCacheDiagnostic(T syntaxNode, CacheDiagnosticFactory diagnostic)
- {
- if (GetKey(syntaxNode) is not { } key) return;
- if (!_foundDiagnosticFactories.TryGetValue(key, out var array))
- {
- array = ImmutableArray.Create(diagnostic).ToBuilder();
- _foundDiagnosticFactories.Add(key, array);
- }
- else
- {
- array.Add(diagnostic);
- }
- }
-
- public abstract void OnVisitNode(T syntaxNode);
- }
-}
diff --git a/src/JsonRpc.Generators/Contexts/DapAttributes.cs b/src/JsonRpc.Generators/Contexts/DapAttributes.cs
index 1f55ce153..d081deade 100644
--- a/src/JsonRpc.Generators/Contexts/DapAttributes.cs
+++ b/src/JsonRpc.Generators/Contexts/DapAttributes.cs
@@ -1,16 +1,14 @@
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
-using OmniSharp.Extensions.JsonRpc.Generators.Cache;
namespace OmniSharp.Extensions.JsonRpc.Generators.Contexts
{
record DapAttributes
{
public static DapAttributes? Parse(
- GeneratorExecutionContext context,
- AddCacheSource addCacheSource,
- ReportCacheDiagnostic cacheDiagnostic,
- TypeDeclarationSyntax syntax,
+ Compilation compilation,
+ TypeDeclarationSyntax candidateClass,
+ SemanticModel model,
INamedTypeSymbol symbol
)
{
diff --git a/src/JsonRpc.Generators/Contexts/ExtensionMethodContext.cs b/src/JsonRpc.Generators/Contexts/ExtensionMethodContext.cs
index 3dc33a5df..49e08ae49 100644
--- a/src/JsonRpc.Generators/Contexts/ExtensionMethodContext.cs
+++ b/src/JsonRpc.Generators/Contexts/ExtensionMethodContext.cs
@@ -9,8 +9,7 @@ record ExtensionMethodContext(
TypeDeclarationSyntax TypeDeclaration,
INamedTypeSymbol TypeSymbol,
TypeSyntax Item,
- ImmutableArray RelatedItems,
- GeneratorExecutionContext Context
+ ImmutableArray RelatedItems
)
{
public bool IsProxy { get; init; }
diff --git a/src/JsonRpc.Generators/Contexts/GeneratorData.cs b/src/JsonRpc.Generators/Contexts/GeneratorData.cs
index a5cd7f311..8af0444e6 100644
--- a/src/JsonRpc.Generators/Contexts/GeneratorData.cs
+++ b/src/JsonRpc.Generators/Contexts/GeneratorData.cs
@@ -1,10 +1,9 @@
+using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
-using Microsoft.CodeAnalysis.Text;
-using OmniSharp.Extensions.JsonRpc.Generators.Cache;
using static OmniSharp.Extensions.JsonRpc.Generators.Helpers;
namespace OmniSharp.Extensions.JsonRpc.Generators.Contexts
@@ -21,38 +20,23 @@ abstract record GeneratorData(
HashSet AdditionalUsings,
List AssemblyJsonRpcHandlersAttributeArguments,
SemanticModel Model,
- GeneratorExecutionContext Context
+ Compilation Compilation
)
{
- private AddCacheSource AddCacheSourceDelegate { get; init; }
- private ReportCacheDiagnostic CacheDiagnosticDelegate { get; init; }
-
- public void AddSource(string hintName, SourceText sourceText)
- {
- AddCacheSourceDelegate(hintName, TypeDeclaration, sourceText);
- }
-
- public void ReportDiagnostic(CacheDiagnosticFactory diagnostic)
- {
- CacheDiagnosticDelegate(TypeDeclaration, diagnostic);
- }
-
public static GeneratorData? Create(
- GeneratorExecutionContext context,
+ Compilation compilation,
TypeDeclarationSyntax candidateClass,
- AddCacheSource addCacheSource,
- ReportCacheDiagnostic cacheDiagnostic,
+ SemanticModel model,
HashSet additionalUsings
)
{
- var model = context.Compilation.GetSemanticModel(candidateClass.SyntaxTree);
- var symbol = model.GetDeclaredSymbol(candidateClass);
+ var symbol = model.GetDeclaredSymbol(candidateClass) is { } nts ? nts : null;
if (symbol == null) return null;
var requestType = GetRequestType(candidateClass, symbol);
if (requestType == null) return null;
- var jsonRpcAttributes = JsonRpcAttributes.Parse(context, addCacheSource, cacheDiagnostic, candidateClass, symbol, additionalUsings);
- var lspAttributes = LspAttributes.Parse(context, addCacheSource, cacheDiagnostic, candidateClass, symbol);
- var dapAttributes = DapAttributes.Parse(context, addCacheSource, cacheDiagnostic, candidateClass, symbol);
+ var jsonRpcAttributes = JsonRpcAttributes.Parse(compilation, candidateClass, model, symbol, additionalUsings);
+ var lspAttributes = LspAttributes.Parse(compilation, candidateClass, model, symbol);
+ var dapAttributes = DapAttributes.Parse(compilation, candidateClass, model, symbol);
additionalUsings.Add(jsonRpcAttributes.HandlerNamespace);
additionalUsings.Add(jsonRpcAttributes.ModelNamespace);
@@ -75,9 +59,8 @@ HashSet additionalUsings
GetPartialItems(candidateClass, symbol, requestType),
additionalUsings,
new List(),
- model,
- context
- ) { CacheDiagnosticDelegate = cacheDiagnostic, AddCacheSourceDelegate = addCacheSource };
+ model, compilation
+ );
}
if (IsNotification(candidateClass))
@@ -93,9 +76,8 @@ HashSet additionalUsings
GetRegistrationOptions(candidateClass, symbol, lspAttributes),
additionalUsings,
new List(),
- model,
- context
- ) { CacheDiagnosticDelegate = cacheDiagnostic, AddCacheSourceDelegate = addCacheSource };
+ model, compilation
+ );
}
return null;
@@ -109,8 +91,7 @@ HashSet additionalUsings
&& tds.AttributeLists.ContainsAttribute("GenerateHandler")
)?.GetSyntax() is TypeDeclarationSyntax declarationSyntax)
{
- return Create(parent.Context, declarationSyntax, parent.AddCacheSourceDelegate, parent.CacheDiagnosticDelegate, parent.AdditionalUsings) as RequestItem;
- }
+ return Create(parent.Compilation, declarationSyntax, parent.Compilation.GetSemanticModel(declarationSyntax.SyntaxTree), parent.AdditionalUsings) as RequestItem; }
return null;
}
diff --git a/src/JsonRpc.Generators/Contexts/JsonRpcAttributes.cs b/src/JsonRpc.Generators/Contexts/JsonRpcAttributes.cs
index f72061692..17b5c6adb 100644
--- a/src/JsonRpc.Generators/Contexts/JsonRpcAttributes.cs
+++ b/src/JsonRpc.Generators/Contexts/JsonRpcAttributes.cs
@@ -5,18 +5,19 @@
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
-using OmniSharp.Extensions.JsonRpc.Generators.Cache;
namespace OmniSharp.Extensions.JsonRpc.Generators.Contexts
{
record JsonRpcAttributes(
SyntaxAttributeData? GenerateHandlerMethods,
ImmutableArray HandlerRegistries,
+ ImmutableArray HandlerRegistryDiagnostics,
string HandlerMethodName,
string PartialHandlerMethodName,
bool AllowDerivedRequests,
SyntaxAttributeData? GenerateRequestMethods,
ImmutableArray RequestProxies,
+ ImmutableArray RequestProxyDiagnostics,
string RequestMethodName,
SyntaxAttributeData? GenerateHandler,
string HandlerNamespace,
@@ -25,27 +26,30 @@ string ModelNamespace
)
{
public static JsonRpcAttributes Parse(
- GeneratorExecutionContext context,
- AddCacheSource addCacheSource,
- ReportCacheDiagnostic cacheDiagnostic,
+ Compilation compilation,
TypeDeclarationSyntax syntax,
+ SemanticModel model,
INamedTypeSymbol symbol,
HashSet additionalUsings
)
{
- var generateHandlerMethodsAttributeSymbol = context.Compilation.GetTypeByMetadataName("OmniSharp.Extensions.JsonRpc.Generation.GenerateHandlerMethodsAttribute");
- var generateRequestMethodsAttributeSymbol = context.Compilation.GetTypeByMetadataName("OmniSharp.Extensions.JsonRpc.Generation.GenerateRequestMethodsAttribute");
- var generateHandlerAttributeSymbol = context.Compilation.GetTypeByMetadataName("OmniSharp.Extensions.JsonRpc.Generation.GenerateHandlerAttribute");
+ var generateHandlerMethodsAttributeSymbol =
+ compilation.GetTypeByMetadataName("OmniSharp.Extensions.JsonRpc.Generation.GenerateHandlerMethodsAttribute");
+ var generateRequestMethodsAttributeSymbol =
+ compilation.GetTypeByMetadataName("OmniSharp.Extensions.JsonRpc.Generation.GenerateRequestMethodsAttribute");
+ var generateHandlerAttributeSymbol = compilation.GetTypeByMetadataName("OmniSharp.Extensions.JsonRpc.Generation.GenerateHandlerAttribute");
var handlerName = Helpers.SpecialCasedHandlerName(symbol).Split('.').Last();
var attributes = new JsonRpcAttributes(
null,
ImmutableArray.Empty,
+ ImmutableArray.Empty,
GetHandlerMethodName(symbol, handlerName),
GetPartialHandlerMethodName(symbol, handlerName),
false,
null,
ImmutableArray.Empty,
+ ImmutableArray.Empty,
GetRequestMethodName(syntax, symbol, handlerName),
null,
symbol.ContainingNamespace.ToDisplayString(),
@@ -55,70 +59,92 @@ HashSet additionalUsings
if (symbol.GetAttribute(generateHandlerAttributeSymbol) is { } generateHandlerData)
{
- attributes = attributes with {
+ attributes = attributes with
+ {
GenerateHandler = SyntaxAttributeData.Parse(generateHandlerData),
AllowDerivedRequests = generateHandlerData
.NamedArguments
.Select(z => z is { Key: "AllowDerivedRequests", Value: { Value: true } })
.Count(z => z) is > 0,
- HandlerNamespace = generateHandlerData is { ConstructorArguments: { Length: >=1 } arguments }
+ HandlerNamespace = generateHandlerData is { ConstructorArguments: { Length: >= 1 } arguments }
? arguments[0].Value as string ?? attributes.HandlerNamespace
: attributes.HandlerNamespace,
HandlerName = generateHandlerData is { NamedArguments: { Length: >= 1 } namedArguments }
? namedArguments
.Select(z => z is { Key: "Name", Value: { Value: string str } } ? str : null)
- .FirstOrDefault(z => z is { Length: >0 }) ?? attributes.HandlerName
+ .FirstOrDefault(z => z is { Length: > 0 }) ?? attributes.HandlerName
: attributes.HandlerName
- };
+ };
- attributes = attributes with {
+ attributes = attributes with
+ {
HandlerMethodName = GetHandlerMethodName(symbol, attributes.HandlerName),
PartialHandlerMethodName = GetPartialHandlerMethodName(symbol, attributes.HandlerName),
RequestMethodName = GetRequestMethodName(syntax, symbol, attributes.HandlerName)
- };
+ };
}
if (symbol.GetAttribute(generateHandlerMethodsAttributeSymbol) is { } generateHandlerMethodsData)
{
var data = SyntaxAttributeData.Parse(generateHandlerMethodsData);
- attributes = attributes with {
+ var diagnostics = new List();
+ var syntaxes = new List();
+ foreach (var registry in GetHandlerRegistries(
+ syntax,
+ generateHandlerMethodsData,
+ symbol,
+ additionalUsings
+ ))
+ {
+ if (registry.diagnostic is { }) diagnostics.Add(registry.diagnostic);
+ if (registry.typeSyntax is { }) syntaxes.Add(registry.typeSyntax);
+ }
+
+ attributes = attributes with
+ {
GenerateHandlerMethods = data,
HandlerMethodName = generateHandlerMethodsData
.NamedArguments
.Select(z => z is { Key: "MethodName", Value: { Value: string value } } ? value : null)
.FirstOrDefault(z => z is not null) ?? attributes.HandlerMethodName,
- HandlerRegistries = GetHandlerRegistries(
- a => cacheDiagnostic(syntax, a),
- generateHandlerMethodsData,
- symbol,
- additionalUsings
- ).ToImmutableArray()
- };
+ HandlerRegistries = syntaxes.ToImmutableArray(),
+ HandlerRegistryDiagnostics = diagnostics.ToImmutableArray()
+ };
}
if (symbol.GetAttribute(generateRequestMethodsAttributeSymbol) is { } generateRequestMethodsData)
{
var data = SyntaxAttributeData.Parse(generateRequestMethodsData);
- attributes = attributes with {
+ var diagnostics = new List();
+ var syntaxes = new List();
+ foreach (var registry in GetRequestProxies(
+ syntax,
+ generateRequestMethodsData,
+ symbol,
+ additionalUsings
+ ))
+ {
+ if (registry.diagnostic is { }) diagnostics.Add(registry.diagnostic);
+ if (registry.typeSyntax is { }) syntaxes.Add(registry.typeSyntax);
+ }
+
+ attributes = attributes with
+ {
GenerateRequestMethods = data,
RequestMethodName = generateRequestMethodsData
.NamedArguments
.Select(z => z is { Key: "MethodName", Value: { Value: string value } } ? value : null)
.FirstOrDefault(z => z is not null) ?? attributes.RequestMethodName,
- RequestProxies = GetRequestProxies(
- (a) => cacheDiagnostic(syntax, a),
- generateRequestMethodsData,
- symbol,
- additionalUsings
- ).ToImmutableArray()
- };
+ RequestProxies = syntaxes.ToImmutableArray(),
+ RequestProxyDiagnostics = diagnostics.ToImmutableArray()
+ };
}
return attributes;
}
- private static IEnumerable GetHandlerRegistries(
- Action> cacheDiagnostic,
+ private static IEnumerable<(TypeSyntax? typeSyntax, Diagnostic? diagnostic)> GetHandlerRegistries(
+ TypeDeclarationSyntax typeDeclarationSyntax,
AttributeData attributeData,
INamedTypeSymbol interfaceType,
HashSet additionalUsings
@@ -130,7 +156,7 @@ HashSet additionalUsings
{
if (item.Expression is TypeOfExpressionSyntax typeOfExpressionSyntax)
{
- yield return typeOfExpressionSyntax.Type;
+ yield return ( typeOfExpressionSyntax.Type, null );
foundValue = true;
}
}
@@ -142,11 +168,15 @@ HashSet additionalUsings
var attribute = interfaceType.GetAttributes().First(z => z.AttributeClass?.Name == "MethodAttribute");
if (attribute.ConstructorArguments.Length < 2)
{
- cacheDiagnostic(static c => Diagnostic.Create(GeneratorDiagnostics.MissingDirection, c.AttributeLists.GetAttribute("GenerateHandlerMethods")?.GetLocation()));
+ yield return ( null, Diagnostic.Create(
+ GeneratorDiagnostics.MissingDirection,
+ typeDeclarationSyntax.AttributeLists.GetAttribute("GenerateHandlerMethods")?.GetLocation()
+ )
+ );
yield break;
}
- var direction = (int) interfaceType.GetAttributes().First(z => z.AttributeClass?.Name == "MethodAttribute").ConstructorArguments[1].Value!;
+ var direction = (int)interfaceType.GetAttributes().First(z => z.AttributeClass?.Name == "MethodAttribute").ConstructorArguments[1].Value!;
/*
Unspecified = 0b0000,
@@ -160,12 +190,12 @@ HashSet additionalUsings
additionalUsings.Add("OmniSharp.Extensions.LanguageServer.Protocol.Server");
if (( direction & 0b0001 ) == 0b0001)
{
- yield return LanguageProtocolServerToClientRegistry;
+ yield return ( LanguageProtocolServerToClientRegistry, null );
}
if (( direction & 0b0010 ) == 0b0010)
{
- yield return LanguageProtocolClientToServerRegistry;
+ yield return ( LanguageProtocolClientToServerRegistry, null );
}
yield break;
@@ -176,11 +206,16 @@ HashSet additionalUsings
var attribute = interfaceType.GetAttributes().First(z => z.AttributeClass?.Name == "MethodAttribute");
if (attribute.ConstructorArguments.Length < 2)
{
- cacheDiagnostic(static c => Diagnostic.Create(GeneratorDiagnostics.MissingDirection, c.AttributeLists.GetAttribute("GenerateHandlerMethods")?.GetLocation()));
+ yield return (
+ null,
+ Diagnostic.Create(
+ GeneratorDiagnostics.MissingDirection, typeDeclarationSyntax.AttributeLists.GetAttribute("GenerateHandlerMethods")?.GetLocation()
+ )
+ );
yield break;
}
- var direction = (int) interfaceType.GetAttributes().First(z => z.AttributeClass?.Name == "MethodAttribute").ConstructorArguments[1].Value!;
+ var direction = (int)interfaceType.GetAttributes().First(z => z.AttributeClass?.Name == "MethodAttribute").ConstructorArguments[1].Value!;
/*
Unspecified = 0b0000,
@@ -194,18 +229,23 @@ HashSet additionalUsings
additionalUsings.Add("OmniSharp.Extensions.DebugAdapter.Protocol.Server");
if (( direction & 0b0001 ) == 0b0001)
{
- yield return DebugProtocolServerToClientRegistry;
+ yield return ( DebugProtocolServerToClientRegistry, null );
}
if (( direction & 0b0010 ) == 0b0010)
{
- yield return DebugProtocolClientToServerRegistry;
+ yield return ( DebugProtocolClientToServerRegistry, null );
}
yield break;
}
- cacheDiagnostic(static c => Diagnostic.Create(GeneratorDiagnostics.CouldNotInferRequestRouter, c.AttributeLists.GetAttribute("GenerateHandlerMethods")?.GetLocation()));
+ yield return (
+ null,
+ Diagnostic.Create(
+ GeneratorDiagnostics.CouldNotInferRequestRouter, typeDeclarationSyntax.AttributeLists.GetAttribute("GenerateHandlerMethods")?.GetLocation()
+ )
+ );
}
private static NameSyntax LanguageProtocolServerToClientRegistry { get; } =
@@ -221,8 +261,8 @@ HashSet additionalUsings
SyntaxFactory.IdentifierName("IDebugAdapterServerRegistry");
- private static IEnumerable GetRequestProxies(
- Action> cacheDiagnostic,
+ private static IEnumerable<(TypeSyntax? typeSyntax, Diagnostic? diagnostic)> GetRequestProxies(
+ TypeDeclarationSyntax typeDeclarationSyntax,
AttributeData attributeData,
INamedTypeSymbol interfaceType,
HashSet additionalUsings
@@ -234,7 +274,7 @@ HashSet additionalUsings
{
if (item.Expression is TypeOfExpressionSyntax typeOfExpressionSyntax)
{
- yield return typeOfExpressionSyntax.Type;
+ yield return ( typeOfExpressionSyntax.Type, null );
foundValue = true;
}
}
@@ -246,11 +286,16 @@ HashSet additionalUsings
var attribute = interfaceType.GetAttributes().First(z => z.AttributeClass?.Name == "MethodAttribute");
if (attribute.ConstructorArguments.Length < 2)
{
- cacheDiagnostic(static c => Diagnostic.Create(GeneratorDiagnostics.MissingDirection, c.AttributeLists.GetAttribute("GenerateRequestMethods")?.GetLocation()));
+ yield return ( null,
+ Diagnostic.Create(
+ GeneratorDiagnostics.MissingDirection,
+ typeDeclarationSyntax.AttributeLists.GetAttribute("GenerateRequestMethods")?.GetLocation()
+ )
+ );
yield break;
}
- var direction = (int) interfaceType.GetAttributes().First(z => z.AttributeClass?.Name == "MethodAttribute")!.ConstructorArguments[1].Value!;
+ var direction = (int)interfaceType.GetAttributes().First(z => z.AttributeClass?.Name == "MethodAttribute")!.ConstructorArguments[1].Value!;
/*
Unspecified = 0b0000,
@@ -265,12 +310,12 @@ HashSet additionalUsings
additionalUsings.Add("OmniSharp.Extensions.LanguageServer.Protocol.Client");
if (( direction & 0b0001 ) == 0b0001)
{
- yield return LanguageProtocolServerToClient;
+ yield return ( LanguageProtocolServerToClient, null );
}
if (( direction & 0b0010 ) == 0b0010)
{
- yield return LanguageProtocolClientToServer;
+ yield return ( LanguageProtocolClientToServer, null );
}
yield break;
@@ -281,11 +326,16 @@ HashSet additionalUsings
var attribute = interfaceType.GetAttributes().First(z => z.AttributeClass?.Name == "MethodAttribute");
if (attribute.ConstructorArguments.Length < 2)
{
- cacheDiagnostic(static c => Diagnostic.Create(GeneratorDiagnostics.MissingDirection, c.AttributeLists.GetAttribute("GenerateRequestMethods")?.GetLocation()));
+ yield return ( null,
+ Diagnostic.Create(
+ GeneratorDiagnostics.MissingDirection,
+ typeDeclarationSyntax.AttributeLists.GetAttribute("GenerateRequestMethods")?.GetLocation()
+ )
+ );
yield break;
}
- var direction = (int) interfaceType.GetAttributes().First(z => z.AttributeClass?.Name == "MethodAttribute").ConstructorArguments[1].Value!;
+ var direction = (int)interfaceType.GetAttributes().First(z => z.AttributeClass?.Name == "MethodAttribute").ConstructorArguments[1].Value!;
/*
Unspecified = 0b0000,
@@ -298,18 +348,23 @@ HashSet additionalUsings
if (( direction & 0b0001 ) == 0b0001)
{
- yield return DebugProtocolServerToClient;
+ yield return ( DebugProtocolServerToClient, null );
}
if (( direction & 0b0010 ) == 0b0010)
{
- yield return DebugProtocolClientToServer;
+ yield return ( DebugProtocolClientToServer, null );
}
yield break;
}
- cacheDiagnostic(static c => Diagnostic.Create(GeneratorDiagnostics.CouldNotInferRequestRouter, c.AttributeLists.GetAttribute("GenerateRequestMethods")?.GetLocation()));
+ yield return ( null,
+ Diagnostic.Create(
+ GeneratorDiagnostics.CouldNotInferRequestRouter,
+ typeDeclarationSyntax.AttributeLists.GetAttribute("GenerateRequestMethods")?.GetLocation()
+ )
+ );
}
private static NameSyntax LanguageProtocolServerToClient { get; } =
diff --git a/src/JsonRpc.Generators/Contexts/LspAttributes.cs b/src/JsonRpc.Generators/Contexts/LspAttributes.cs
index 4c55f36e2..3dda28f14 100644
--- a/src/JsonRpc.Generators/Contexts/LspAttributes.cs
+++ b/src/JsonRpc.Generators/Contexts/LspAttributes.cs
@@ -1,7 +1,6 @@
using System.Linq;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
-using OmniSharp.Extensions.JsonRpc.Generators.Cache;
namespace OmniSharp.Extensions.JsonRpc.Generators.Contexts
{
@@ -23,10 +22,9 @@ bool CanHaveData
)
{
public static LspAttributes? Parse(
- GeneratorExecutionContext context,
- AddCacheSource addCacheSource,
- ReportCacheDiagnostic cacheDiagnostic,
+ Compilation compilation,
TypeDeclarationSyntax syntax,
+ SemanticModel model,
INamedTypeSymbol symbol)
{
var prefix = "OmniSharp.Extensions.LanguageServer.Protocol.Generation";
@@ -40,7 +38,7 @@ bool CanHaveData
};
{
- var attributeSymbol = context.Compilation.GetTypeByMetadataName($"{prefix}.GenerateTypedDataAttribute");
+ var attributeSymbol = compilation.GetTypeByMetadataName($"{prefix}.GenerateTypedDataAttribute");
if (symbol.GetAttribute(attributeSymbol) is { } data && data.ApplicationSyntaxReference?.GetSyntax() is AttributeSyntax attributeSyntax)
{
attributes = attributes with {
@@ -50,7 +48,7 @@ bool CanHaveData
}
}
{
- var attributeSymbol = context.Compilation.GetTypeByMetadataName($"{prefix}.GenerateContainerAttribute");
+ var attributeSymbol = compilation.GetTypeByMetadataName($"{prefix}.GenerateContainerAttribute");
if (symbol.GetAttribute(attributeSymbol) is { } data && data.ApplicationSyntaxReference?.GetSyntax() is AttributeSyntax attributeSyntax)
{
attributes = attributes with {
@@ -60,7 +58,7 @@ bool CanHaveData
}
}
{
- var attributeSymbol = context.Compilation.GetTypeByMetadataName($"{prefix}.RegistrationOptionsKeyAttribute");
+ var attributeSymbol = compilation.GetTypeByMetadataName($"{prefix}.RegistrationOptionsKeyAttribute");
if (symbol.GetAttribute(attributeSymbol) is { ConstructorArguments: { Length: >=1 } arguments } data
&& arguments[0].Kind is TypedConstantKind.Primitive && arguments[0].Value is string value
&& data.ApplicationSyntaxReference?.GetSyntax() is AttributeSyntax attributeSyntax)
@@ -72,21 +70,21 @@ bool CanHaveData
}
}
{
- var (syntaxAttributeData, syntaxSymbol) = ExtractAttributeTypeData(symbol, context.Compilation.GetTypeByMetadataName($"{prefix}.CapabilityAttribute"));
+ var (syntaxAttributeData, syntaxSymbol) = ExtractAttributeTypeData(symbol, compilation.GetTypeByMetadataName($"{prefix}.CapabilityAttribute"));
attributes = attributes with {
CapabilityAttribute = syntaxAttributeData,
Capability = syntaxSymbol
};
}
{
- var (syntaxAttributeData, syntaxSymbol) = ExtractAttributeTypeData(symbol, context.Compilation.GetTypeByMetadataName($"{prefix}.ResolverAttribute"));
+ var (syntaxAttributeData, syntaxSymbol) = ExtractAttributeTypeData(symbol, compilation.GetTypeByMetadataName($"{prefix}.ResolverAttribute"));
attributes = attributes with {
ResolverAttribute = syntaxAttributeData,
Resolver = syntaxSymbol
};
}
{
- var (syntaxAttributeData, syntaxSymbol) = ExtractAttributeTypeData(symbol, context.Compilation.GetTypeByMetadataName($"{prefix}.RegistrationOptionsAttribute"));
+ var (syntaxAttributeData, syntaxSymbol) = ExtractAttributeTypeData(symbol, compilation.GetTypeByMetadataName($"{prefix}.RegistrationOptionsAttribute"));
attributes = attributes with {
RegistrationOptionsAttribute = syntaxAttributeData,
RegistrationOptions = syntaxSymbol
diff --git a/src/JsonRpc.Generators/Contexts/NotificationItem.cs b/src/JsonRpc.Generators/Contexts/NotificationItem.cs
index 6d9d7a111..24b2eab64 100644
--- a/src/JsonRpc.Generators/Contexts/NotificationItem.cs
+++ b/src/JsonRpc.Generators/Contexts/NotificationItem.cs
@@ -16,10 +16,10 @@ record NotificationItem(
HashSet AdditionalUsings,
List AssemblyJsonRpcHandlersAttributeArguments,
SemanticModel Model,
- GeneratorExecutionContext Context
+ Compilation Compilation
) : GeneratorData(
TypeDeclaration, TypeSymbol, JsonRpcAttributes, LspAttributes,
DapAttributes, Request, Capability, RegistrationOptions,
- AdditionalUsings, AssemblyJsonRpcHandlersAttributeArguments, Model, Context
+ AdditionalUsings, AssemblyJsonRpcHandlersAttributeArguments, Model, Compilation
);
}
diff --git a/src/JsonRpc.Generators/Contexts/RegistrationOptionAttributes.cs b/src/JsonRpc.Generators/Contexts/RegistrationOptionAttributes.cs
index f94a2844d..dd19d8100 100644
--- a/src/JsonRpc.Generators/Contexts/RegistrationOptionAttributes.cs
+++ b/src/JsonRpc.Generators/Contexts/RegistrationOptionAttributes.cs
@@ -20,18 +20,18 @@ record RegistrationOptionAttributes(
bool ImplementsStaticRegistrationOptions
)
{
- public static RegistrationOptionAttributes? Parse(GeneratorExecutionContext context, TypeDeclarationSyntax syntax, INamedTypeSymbol symbol)
+ public static RegistrationOptionAttributes? Parse(Compilation compilation, TypeDeclarationSyntax syntax, INamedTypeSymbol symbol)
{
var registrationOptionsAttributeSymbol =
- context.Compilation.GetTypeByMetadataName($"OmniSharp.Extensions.LanguageServer.Protocol.Generation.GenerateRegistrationOptionsAttribute");
+ compilation.GetTypeByMetadataName($"OmniSharp.Extensions.LanguageServer.Protocol.Generation.GenerateRegistrationOptionsAttribute");
var registrationOptionsConverterAttributeSymbol =
- context.Compilation.GetTypeByMetadataName($"OmniSharp.Extensions.LanguageServer.Protocol.RegistrationOptionsConverterAttribute");
-// var registrationOptionsInterfaceSymbol = context.Compilation.GetTypeByMetadataName("OmniSharp.Extensions.LanguageServer.Protocol.IRegistrationOptions");
+ compilation.GetTypeByMetadataName($"OmniSharp.Extensions.LanguageServer.Protocol.RegistrationOptionsConverterAttribute");
+// var registrationOptionsInterfaceSymbol = compilation.GetTypeByMetadataName("OmniSharp.Extensions.LanguageServer.Protocol.IRegistrationOptions");
var textDocumentRegistrationOptionsInterfaceSymbol =
- context.Compilation.GetTypeByMetadataName("OmniSharp.Extensions.LanguageServer.Protocol.Models.ITextDocumentRegistrationOptions");
- var workDoneProgressOptionsInterfaceSymbol = context.Compilation.GetTypeByMetadataName("OmniSharp.Extensions.LanguageServer.Protocol.Models.IWorkDoneProgressOptions");
+ compilation.GetTypeByMetadataName("OmniSharp.Extensions.LanguageServer.Protocol.Models.ITextDocumentRegistrationOptions");
+ var workDoneProgressOptionsInterfaceSymbol = compilation.GetTypeByMetadataName("OmniSharp.Extensions.LanguageServer.Protocol.Models.IWorkDoneProgressOptions");
var staticRegistrationOptionsInterfaceSymbol =
- context.Compilation.GetTypeByMetadataName("OmniSharp.Extensions.LanguageServer.Protocol.Models.IStaticRegistrationOptions");
+ 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;
diff --git a/src/JsonRpc.Generators/Contexts/RequestItem.cs b/src/JsonRpc.Generators/Contexts/RequestItem.cs
index 109d2ab88..3b5103243 100644
--- a/src/JsonRpc.Generators/Contexts/RequestItem.cs
+++ b/src/JsonRpc.Generators/Contexts/RequestItem.cs
@@ -20,11 +20,11 @@ record RequestItem(
HashSet AdditionalUsings,
List AssemblyJsonRpcHandlersAttributeArguments,
SemanticModel Model,
- GeneratorExecutionContext Context
+ Compilation Compilation
) : GeneratorData(
TypeDeclaration, TypeSymbol,
JsonRpcAttributes, LspAttributes, DapAttributes, Request, Capability, RegistrationOptions,
- AdditionalUsings, AssemblyJsonRpcHandlersAttributeArguments, Model, Context
+ AdditionalUsings, AssemblyJsonRpcHandlersAttributeArguments, Model, Compilation
);
// record PartialItem(TypeSyntax Syntax, INamedTypeSymbol Symbol, SyntaxSymbol Item) : SyntaxSymbol(Syntax, Symbol);
diff --git a/src/JsonRpc.Generators/EnumLikeStringGenerator.cs b/src/JsonRpc.Generators/EnumLikeStringGenerator.cs
index bef33165e..25d2b6e42 100644
--- a/src/JsonRpc.Generators/EnumLikeStringGenerator.cs
+++ b/src/JsonRpc.Generators/EnumLikeStringGenerator.cs
@@ -5,67 +5,55 @@
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
-using OmniSharp.Extensions.JsonRpc.Generators.Cache;
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
namespace OmniSharp.Extensions.JsonRpc.Generators
{
[Generator]
- public class EnumLikeStringGenerator : CachedSourceGenerator
+ public class EnumLikeStringGenerator : IIncrementalGenerator
{
- protected override void Execute(
- GeneratorExecutionContext context, SyntaxReceiver syntaxReceiver, AddCacheSource addCacheSource,
- ReportCacheDiagnostic cacheDiagnostic
- )
+ public void Initialize(IncrementalGeneratorInitializationContext context)
{
- foreach (var candidate in syntaxReceiver.Candidates)
- {
- var model = context.Compilation.GetSemanticModel(candidate.SyntaxTree);
- var symbol = model.GetDeclaredSymbol(candidate);
- if (symbol is null) continue;
+ var syntaxProvider = context.SyntaxProvider.CreateSyntaxProvider(
+ predicate: (node, token) => node is StructDeclarationSyntax tds && tds.AttributeLists.ContainsAttribute("StringEnum"),
+ transform: (syntaxContext, token) => syntaxContext
+ );
+
+ context.RegisterSourceOutput(syntaxProvider, GenerateEnum);
+ }
- if (!candidate.Modifiers.Any(z => z.IsKind(SyntaxKind.PartialKeyword)))
- {
- cacheDiagnostic(candidate, static c => Diagnostic.Create(GeneratorDiagnostics.MustBePartial, c.Identifier.GetLocation(), c.Identifier.Text));
- continue;
- }
+ private void GenerateEnum(SourceProductionContext context, GeneratorSyntaxContext syntaxContext)
+ {
+ var candidate = (StructDeclarationSyntax)syntaxContext.Node;
+ var model = syntaxContext.SemanticModel;
+ var symbol = model.GetDeclaredSymbol(syntaxContext.Node);
+ if (symbol is null) return;
- if (!candidate.Modifiers.Any(z => z.IsKind(SyntaxKind.ReadOnlyKeyword)))
- {
- cacheDiagnostic(candidate, static c => Diagnostic.Create(GeneratorDiagnostics.MustBeReadOnly, c.Identifier.GetLocation(), c.Identifier.Text));
- continue;
- }
+ if (!candidate.Modifiers.Any(z => z.IsKind(SyntaxKind.PartialKeyword)))
+ {
+ context.ReportDiagnostic(Diagnostic.Create(GeneratorDiagnostics.MustBePartial, candidate.Identifier.GetLocation(), candidate.Identifier.Text));
+ return;
+ }
- var cu = CompilationUnit(
- List(),
- List(),
- List(),
- SingletonList(
- NamespaceDeclaration(ParseName(symbol.ContainingNamespace.ToDisplayString()))
- .WithMembers(SingletonList(GetImplementation(candidate)))
- )
- )
- .AddUsings(
- UsingDirective(ParseName("System")),
- UsingDirective(ParseName("System.Collections.Generic")),
- UsingDirective(ParseName("System.Diagnostics")),
- UsingDirective(ParseName("System.Linq")),
- UsingDirective(ParseName("System.Reflection")),
- UsingDirective(ParseName("Newtonsoft.Json")),
- UsingDirective(ParseName("OmniSharp.Extensions.JsonRpc")),
- UsingDirective(ParseName("OmniSharp.Extensions.JsonRpc.Serialization.Converters"))
+ if (!candidate.Modifiers.Any(z => z.IsKind(SyntaxKind.ReadOnlyKeyword)))
+ {
+ context.ReportDiagnostic(Diagnostic.Create(GeneratorDiagnostics.MustBeReadOnly, candidate.Identifier.GetLocation(), candidate.Identifier.Text));
+ return;
+ }
+
+ var cu = CompilationUnit(
+ List(), List(), List(), SingletonList(
+ NamespaceDeclaration(ParseName(symbol.ContainingNamespace.ToDisplayString()))
+ .WithMembers(SingletonList(GetImplementation(candidate)))
)
- .WithLeadingTrivia()
- .WithTrailingTrivia()
- .WithLeadingTrivia(Comment(Preamble.GeneratedByATool), Trivia(NullableDirectiveTrivia(Token(SyntaxKind.EnableKeyword), true)))
- .WithTrailingTrivia(Trivia(NullableDirectiveTrivia(Token(SyntaxKind.RestoreKeyword), true)), CarriageReturnLineFeed);
+ )
+ .AddUsings(UsingDirective(ParseName("System")), UsingDirective(ParseName("System.Collections.Generic")), UsingDirective(ParseName("System.Diagnostics")), UsingDirective(ParseName("System.Linq")), UsingDirective(ParseName("System.Reflection")), UsingDirective(ParseName("Newtonsoft.Json")), UsingDirective(ParseName("OmniSharp.Extensions.JsonRpc")), UsingDirective(ParseName("OmniSharp.Extensions.JsonRpc.Serialization.Converters")))
+ .WithLeadingTrivia()
+ .WithTrailingTrivia()
+ .WithLeadingTrivia(Trivia(NullableDirectiveTrivia(Token(SyntaxKind.EnableKeyword), true)))
+ .WithTrailingTrivia(Trivia(NullableDirectiveTrivia(Token(SyntaxKind.RestoreKeyword), true)));
- addCacheSource(
- $"{Path.GetFileNameWithoutExtension(candidate.SyntaxTree.FilePath)}_{candidate.Identifier.Text}{( candidate.Arity > 0 ? candidate.Arity.ToString() : "" )}.cs",
- candidate,
- cu.NormalizeWhitespace().GetText(Encoding.UTF8)
- );
- }
+ context.AddSource($"{Path.GetFileNameWithoutExtension(candidate.SyntaxTree.FilePath)}_{candidate.Identifier.Text}{( candidate.Arity > 0 ? candidate.Arity.ToString() : "" )}.cs", cu.NormalizeWhitespace().GetText(Encoding.UTF8));
}
private static StructDeclarationSyntax GetImplementation(StructDeclarationSyntax syntax)
@@ -862,45 +850,5 @@ private static StructDeclarationSyntax GetImplementation(StructDeclarationSyntax
)
;
}
-
- public EnumLikeStringGenerator() : base(() => new SyntaxReceiver(Cache))
- {
- }
-
- public static CacheContainer Cache = new();
-
- public class SyntaxReceiver : SyntaxReceiverCache
- {
- public List Candidates { get; } = new();
-
- public SyntaxReceiver(CacheContainer cacheContainer) : base(cacheContainer)
- {
- }
-
- public override string? GetKey(StructDeclarationSyntax syntax)
- {
- var hasher = new CacheKeyHasher();
- hasher.Append(syntax.SyntaxTree.FilePath);
- hasher.Append(syntax.Keyword.Text);
- hasher.Append(syntax.Identifier.Text);
- hasher.Append(syntax.TypeParameterList);
- hasher.Append(syntax.AttributeLists);
- hasher.Append(syntax.BaseList);
-
- return hasher;
- }
-
- ///
- /// Called for every syntax node in the compilation, we can inspect the nodes and save any information useful for generation
- ///
- public override void OnVisitNode(StructDeclarationSyntax syntaxNode)
- {
- // any field with at least one attribute is a candidate for property generation
- if (syntaxNode.AttributeLists.ContainsAttribute("StringEnum"))
- {
- Candidates.Add(syntaxNode);
- }
- }
- }
}
}
diff --git a/src/JsonRpc.Generators/GenerateHandlerMethodsGenerator.cs b/src/JsonRpc.Generators/GenerateHandlerMethodsGenerator.cs
index a07d42697..9f954c748 100644
--- a/src/JsonRpc.Generators/GenerateHandlerMethodsGenerator.cs
+++ b/src/JsonRpc.Generators/GenerateHandlerMethodsGenerator.cs
@@ -7,7 +7,6 @@
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
-using OmniSharp.Extensions.JsonRpc.Generators.Cache;
using OmniSharp.Extensions.JsonRpc.Generators.Contexts;
using OmniSharp.Extensions.JsonRpc.Generators.Strategies;
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
@@ -15,155 +14,167 @@
namespace OmniSharp.Extensions.JsonRpc.Generators
{
[Generator]
- public class GenerateHandlerMethodsGenerator : CachedSourceGenerator
+ public class GenerateHandlerMethodsGenerator : IIncrementalGenerator
{
- protected override void Execute(
- GeneratorExecutionContext context, SyntaxReceiver syntaxReceiver, AddCacheSource addCacheSource,
- ReportCacheDiagnostic cacheDiagnostic
- )
+ public void Initialize(IncrementalGeneratorInitializationContext context)
{
- var handlers = new List();
- foreach (var candidateClass in syntaxReceiver.Candidates)
+ var _attributes = "GenerateHandler,GenerateRequestMethods,GenerateHandlerMethods";
+ var syntaxProvider = context.SyntaxProvider.CreateSyntaxProvider(
+ predicate: (syntaxNode, token) =>
+ syntaxNode is TypeDeclarationSyntax tds
+ and (ClassDeclarationSyntax or RecordDeclarationSyntax or InterfaceDeclarationSyntax)
+ && tds.AttributeLists.ContainsAttribute(_attributes), transform: (syntaxContext, token) => syntaxContext
+ )
+ .Combine(context.CompilationProvider)
+ .Select(
+ (tuple, token) =>
+ {
+ var (syntaxContext, compilaiton) = tuple;
+ var additionalUsings = new HashSet
+ {
+ "System",
+ "System.Collections.Generic",
+ "System.Threading",
+ "System.Threading.Tasks",
+ "MediatR",
+ "Microsoft.Extensions.DependencyInjection"
+ };
+
+ GeneratorData? actionItem = null;
+ Diagnostic? diagnostic = null;
+
+ try
+ {
+ actionItem = GeneratorData.Create(
+ compilaiton, (TypeDeclarationSyntax)syntaxContext.Node, syntaxContext.SemanticModel, additionalUsings
+ );
+ }
+ catch (Exception e)
+ {
+ diagnostic = Diagnostic.Create(
+ GeneratorDiagnostics.Exception, syntaxContext.Node.GetLocation(), e.Message,
+ e.StackTrace ?? string.Empty
+ );
+ Debug.WriteLine(e);
+ Debug.WriteLine(e.StackTrace);
+ }
+
+ return ( actionItem, diagnostic, additionalUsings );
+ }
+ );
+
+ context.RegisterSourceOutput(syntaxProvider, GenerateHandlerMethods);
+ context.RegisterSourceOutput(syntaxProvider.Where(z => z.actionItem is {}).SelectMany((z, _) => z.actionItem!.AssemblyJsonRpcHandlersAttributeArguments).Collect(), GenerateAssemblyJsonRpcHandlers);
+ }
+
+ private void GenerateHandlerMethods(SourceProductionContext context, (GeneratorData? actionItem, Diagnostic? diagnostic, HashSet additionalUsings) valueTuple)
+ {
+ var (actionItem, diagnostic, additionalUsings) = valueTuple;
+ // context.ReportDiagnostic(Diagnostic.Create(GeneratorDiagnostics.Message, null, $"candidate: {candidateClass.Identifier.ToFullString()}"));
+ // can this be async???
+ context.CancellationToken.ThrowIfCancellationRequested();
+
+ if (actionItem is null)
{
-// context.ReportDiagnostic(Diagnostic.Create(GeneratorDiagnostics.Message, null, $"candidate: {candidateClass.Identifier.ToFullString()}"));
- // can this be async???
- context.CancellationToken.ThrowIfCancellationRequested();
-
- var additionalUsings = new HashSet {
- "System",
- "System.Collections.Generic",
- "System.Threading",
- "System.Threading.Tasks",
- "MediatR",
- "Microsoft.Extensions.DependencyInjection"
- };
-
- GeneratorData? actionItem = null;
-
- try
- {
- actionItem = GeneratorData.Create(context, candidateClass, addCacheSource, cacheDiagnostic, additionalUsings);
- }
- catch (Exception e)
- {
- context.ReportDiagnostic(Diagnostic.Create(GeneratorDiagnostics.Exception, candidateClass.GetLocation(), e.Message, e.StackTrace ?? string.Empty));
- Debug.WriteLine(e);
- Debug.WriteLine(e.StackTrace);
- }
+ context.ReportDiagnostic(diagnostic!);
+ return;
+ }
- if (actionItem is null) continue;
-
- var members = CompilationUnitGeneratorStrategies.Aggregate(
- new List(), (m, strategy) => {
- try
- {
- m.AddRange(strategy.Apply(actionItem));
- }
- catch (Exception e)
- {
- context.ReportDiagnostic(
- Diagnostic.Create(
- GeneratorDiagnostics.Exception, candidateClass.GetLocation(), $"Strategy {strategy.GetType().FullName} failed!" + " - " + e.Message,
- e.StackTrace ?? string.Empty
- )
- );
- Debug.WriteLine($"Strategy {strategy.GetType().FullName} failed!");
- Debug.WriteLine(e);
- Debug.WriteLine(e.StackTrace);
- }
-
- return m;
- }
- );
-
- if (!members.Any()) continue;
-
- var namespacesMapping = new Dictionary() {
- ["OmniSharp.Extensions.DebugAdapter"] = new[] {
- "OmniSharp.Extensions.DebugAdapter.Protocol",
- "OmniSharp.Extensions.DebugAdapter.Protocol.Models",
- "OmniSharp.Extensions.DebugAdapter.Protocol.Events",
- "OmniSharp.Extensions.DebugAdapter.Protocol.Requests"
- },
- ["OmniSharp.Extensions.LanguageProtocol"] = new[] {
- "OmniSharp.Extensions.LanguageServer.Protocol",
- "OmniSharp.Extensions.LanguageServer.Protocol.Models"
- },
- };
-
- foreach (var assembly in actionItem.Context.Compilation.References
- .Select(actionItem.Context.Compilation.GetAssemblyOrModuleSymbol)
- .OfType()
- .Concat(new[] { actionItem.Context.Compilation.Assembly }))
+ var candidateClass = actionItem.TypeDeclaration;
+
+ var members = CompilationUnitGeneratorStrategies.Aggregate(
+ new List(), (m, strategy) =>
{
- if (namespacesMapping.TryGetValue(assembly.Name, out var additionalNamespaceUsings))
+ try
{
- foreach (var item in additionalNamespaceUsings)
- {
- additionalUsings.Add(item);
- }
+ m.AddRange(strategy.Apply(context, actionItem));
}
+ catch (Exception e)
+ {
+ context.ReportDiagnostic(
+ Diagnostic.Create(
+ GeneratorDiagnostics.Exception, candidateClass.GetLocation(),
+ $"Strategy {strategy.GetType().FullName} failed!" + " - " + e.Message, e.StackTrace ?? string.Empty
+ )
+ );
+ Debug.WriteLine($"Strategy {strategy.GetType().FullName} failed!");
+ Debug.WriteLine(e);
+ Debug.WriteLine(e.StackTrace);
+ }
+
+ return m;
}
+ );
- var existingUsings = candidateClass.SyntaxTree.GetCompilationUnitRoot()
- .Usings
- .Select(x => x.WithoutTrivia())
- .Union(
- additionalUsings
- .Except(
- candidateClass.SyntaxTree.GetCompilationUnitRoot()
- .Usings
- .Where(z => z.Alias == null)
- .Select(z => z.Name.ToFullString())
- )
- .Except(new [] { "" }) // I think there is a better way... but for now..
- .Distinct()
- .Select(z => UsingDirective(IdentifierName(z)))
- )
- .OrderBy(x => x.Name.ToFullString())
- .ToImmutableArray();
-
- var cu = CompilationUnit(
- List(),
- List(existingUsings),
- List(),
- List(members)
- )
- .WithLeadingTrivia(Comment(Preamble.GeneratedByATool))
- .WithTrailingTrivia(CarriageReturnLineFeed);
-
- addCacheSource(
- $"{candidateClass.Identifier.Text}{( candidateClass.Arity > 0 ? candidateClass.Arity.ToString() : "" )}.cs",
- candidateClass,
- cu.NormalizeWhitespace().GetText(Encoding.UTF8)
- );
-
- handlers.AddRange(actionItem.AssemblyJsonRpcHandlersAttributeArguments);
- }
+ if (!members.Any()) return;
+ var namespacesMapping = new Dictionary()
+ {
+ ["OmniSharp.Extensions.DebugAdapter"] = new[]
+ {
+ "OmniSharp.Extensions.DebugAdapter.Protocol", "OmniSharp.Extensions.DebugAdapter.Protocol.Models",
+ "OmniSharp.Extensions.DebugAdapter.Protocol.Events", "OmniSharp.Extensions.DebugAdapter.Protocol.Requests"
+ },
+ ["OmniSharp.Extensions.LanguageProtocol"] = new[]
+ { "OmniSharp.Extensions.LanguageServer.Protocol", "OmniSharp.Extensions.LanguageServer.Protocol.Models" },
+ };
+
+ foreach (var assembly in actionItem.Compilation.References.Select(actionItem.Compilation.GetAssemblyOrModuleSymbol)
+ .OfType()
+ .Concat(new[] { actionItem.Compilation.Assembly }))
{
- var namespaces = new HashSet() { "OmniSharp.Extensions.JsonRpc" };
- if (handlers.Any())
+ if (namespacesMapping.TryGetValue(assembly.Name, out var additionalNamespaceUsings))
{
- var types = handlers.ToArray();
- var cu = CompilationUnit()
- .WithUsings(List(namespaces.OrderBy(z => z).Select(z => UsingDirective(ParseName(z)))))
- .WithLeadingTrivia(Comment(Preamble.GeneratedByATool))
- .WithTrailingTrivia(CarriageReturnLineFeed);
- while (types.Length > 0)
+ foreach (var item in additionalNamespaceUsings)
{
- var innerTypes = types.Take(10).ToArray();
- types = types.Skip(10).ToArray();
- cu = cu.AddAttributeLists(
- AttributeList(
- target: AttributeTargetSpecifier(Token(SyntaxKind.AssemblyKeyword)),
- SingletonSeparatedList(Attribute(IdentifierName("AssemblyJsonRpcHandlers"), AttributeArgumentList(SeparatedList(innerTypes))))
- )
- );
+ additionalUsings.Add(item);
}
+ }
+ }
- context.AddSource("GeneratedAssemblyJsonRpcHandlers.cs", cu.NormalizeWhitespace().GetText(Encoding.UTF8));
+ var existingUsings = candidateClass.SyntaxTree.GetCompilationUnitRoot()
+ .Usings.Select(x => x.WithoutTrivia())
+ .Union(
+ additionalUsings.Except(
+ candidateClass.SyntaxTree.GetCompilationUnitRoot()
+ .Usings.Where(z => z.Alias == null)
+ .Select(z => z.Name.ToFullString())
+ )
+ .Except(new[] { "" }) // I think there is a better way... but for now..
+ .Distinct()
+ .Select(z => UsingDirective(IdentifierName(z)))
+ )
+ .OrderBy(x => x.Name.ToFullString())
+ .ToImmutableArray();
+
+ var cu = CompilationUnit(List(), List(existingUsings), List(), List(members));
+
+ context.AddSource(
+ $"{candidateClass.Identifier.Text}{( candidateClass.Arity > 0 ? candidateClass.Arity.ToString() : "" )}.cs",
+ cu.NormalizeWhitespace().GetText(Encoding.UTF8)
+ );
+ }
+
+ private void GenerateAssemblyJsonRpcHandlers(SourceProductionContext context, ImmutableArray handlers)
+ {
+ var namespaces = new HashSet() { "OmniSharp.Extensions.JsonRpc" };
+ if (handlers.Any())
+ {
+ var cu = CompilationUnit()
+ .WithUsings(List(namespaces.OrderBy(z => z).Select(z => UsingDirective(ParseName(z)))));
+ while (handlers.Length > 0)
+ {
+ var innerTypes = handlers.Take(10).ToArray();
+ handlers = handlers.Skip(10).ToImmutableArray();
+ cu = cu.AddAttributeLists(
+ AttributeList(
+ target: AttributeTargetSpecifier(Token(SyntaxKind.AssemblyKeyword)),
+ SingletonSeparatedList(Attribute(IdentifierName("AssemblyJsonRpcHandlers"), AttributeArgumentList(SeparatedList(innerTypes))))
+ )
+ );
}
+
+ context.AddSource("GeneratedAssemblyJsonRpcHandlers.cs", cu.NormalizeWhitespace().GetText(Encoding.UTF8));
}
}
@@ -196,46 +207,5 @@ private static ImmutableArray GetCompilationU
);
return compilationUnitStrategies;
}
-
- public GenerateHandlerMethodsGenerator() : base(() => new SyntaxReceiver(Cache))
- {
- }
-
- public static CacheContainer Cache = new();
-
- public class SyntaxReceiver : SyntaxReceiverCache
- {
- private string _attributes;
- public List Candidates { get; } = new();
-
- public SyntaxReceiver(CacheContainer cache) : base(cache)
- {
- _attributes = "GenerateHandler,GenerateRequestMethods,GenerateHandlerMethods";
- }
-
- public override string? GetKey(TypeDeclarationSyntax syntax)
- {
- var hasher = new CacheKeyHasher();
- hasher.Append(syntax.SyntaxTree.FilePath);
- hasher.Append(syntax.Keyword.Text);
- hasher.Append(syntax.Identifier.Text);
- hasher.Append(syntax.TypeParameterList);
- hasher.Append(syntax.AttributeLists);
- hasher.Append(syntax.BaseList);
- return hasher;
- }
-
- ///
- /// Called for every syntax node in the compilation, we can inspect the nodes and save any information useful for generation
- ///
- public override void OnVisitNode(TypeDeclarationSyntax syntaxNode)
- {
- // any field with at least one attribute is a candidate for property generation
- if (syntaxNode is ClassDeclarationSyntax or RecordDeclarationSyntax or InterfaceDeclarationSyntax && syntaxNode.AttributeLists.ContainsAttribute(_attributes))
- {
- Candidates.Add(syntaxNode);
- }
- }
- }
}
}
diff --git a/src/JsonRpc.Generators/ICompilationUnitGeneratorStrategy.cs b/src/JsonRpc.Generators/ICompilationUnitGeneratorStrategy.cs
index c3a147903..d7cc10336 100644
--- a/src/JsonRpc.Generators/ICompilationUnitGeneratorStrategy.cs
+++ b/src/JsonRpc.Generators/ICompilationUnitGeneratorStrategy.cs
@@ -1,4 +1,5 @@
using System.Collections.Generic;
+using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using OmniSharp.Extensions.JsonRpc.Generators.Contexts;
@@ -6,6 +7,6 @@ namespace OmniSharp.Extensions.JsonRpc.Generators
{
internal interface ICompilationUnitGeneratorStrategy
{
- IEnumerable Apply(GeneratorData item);
+ IEnumerable Apply(SourceProductionContext context, GeneratorData item);
}
}
diff --git a/src/JsonRpc.Generators/IExtensionMethodContextGeneratorStrategy.cs b/src/JsonRpc.Generators/IExtensionMethodContextGeneratorStrategy.cs
index 7160e8285..8d3e5bff8 100644
--- a/src/JsonRpc.Generators/IExtensionMethodContextGeneratorStrategy.cs
+++ b/src/JsonRpc.Generators/IExtensionMethodContextGeneratorStrategy.cs
@@ -1,4 +1,5 @@
using System.Collections.Generic;
+using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using OmniSharp.Extensions.JsonRpc.Generators.Contexts;
@@ -6,6 +7,6 @@ namespace OmniSharp.Extensions.JsonRpc.Generators
{
internal interface IExtensionMethodContextGeneratorStrategy
{
- IEnumerable Apply(ExtensionMethodContext extensionMethodContext, GeneratorData item);
+ IEnumerable Apply(SourceProductionContext context, ExtensionMethodContext extensionMethodContext, GeneratorData item);
}
}
diff --git a/src/JsonRpc.Generators/IExtensionMethodGeneratorStrategy.cs b/src/JsonRpc.Generators/IExtensionMethodGeneratorStrategy.cs
index c1bf09b8b..537177649 100644
--- a/src/JsonRpc.Generators/IExtensionMethodGeneratorStrategy.cs
+++ b/src/JsonRpc.Generators/IExtensionMethodGeneratorStrategy.cs
@@ -1,4 +1,5 @@
using System.Collections.Generic;
+using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using OmniSharp.Extensions.JsonRpc.Generators.Contexts;
@@ -6,6 +7,6 @@ namespace OmniSharp.Extensions.JsonRpc.Generators
{
internal interface IExtensionMethodGeneratorStrategy
{
- IEnumerable Apply(GeneratorData item);
+ IEnumerable Apply(SourceProductionContext context, GeneratorData item);
}
}
diff --git a/src/JsonRpc.Generators/JsonRpc.Generators.csproj b/src/JsonRpc.Generators/JsonRpc.Generators.csproj
index 8f0a15cc0..7854d8f6f 100644
--- a/src/JsonRpc.Generators/JsonRpc.Generators.csproj
+++ b/src/JsonRpc.Generators/JsonRpc.Generators.csproj
@@ -11,15 +11,15 @@
-
-
+
+
<_Parameter1>Generation.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100391db875e68eb4bfef49ce14313b9e13f2cd3cc89eb273bbe6c11a55044c7d4f566cf092e1c77ef9e7c75b1496ae7f95d925938f5a01793dd8d9f99ae0a7595779b71b971287d7d7b5960d052078d14f5ce1a85ea5c9fb2f59ac735ff7bc215cab469b7c3486006860bad6f4c3b5204ea2f28dd4e1d05e2cca462cfd593b9f9f
-
+
diff --git a/src/JsonRpc.Generators/RegistrationOptionsGenerator.cs b/src/JsonRpc.Generators/RegistrationOptionsGenerator.cs
index 00884886a..edf1356f9 100644
--- a/src/JsonRpc.Generators/RegistrationOptionsGenerator.cs
+++ b/src/JsonRpc.Generators/RegistrationOptionsGenerator.cs
@@ -1,284 +1,358 @@
using System;
using System.Collections.Generic;
+using System.Collections.Immutable;
using System.Diagnostics;
using System.Linq;
using System.Text;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
-using OmniSharp.Extensions.JsonRpc.Generators.Cache;
using OmniSharp.Extensions.JsonRpc.Generators.Contexts;
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
namespace OmniSharp.Extensions.JsonRpc.Generators
{
[Generator]
- public class RegistrationOptionsGenerator : CachedSourceGenerator
+ public class RegistrationOptionsGenerator : IIncrementalGenerator
{
- private static string[] RequiredUsings = {
+ private static string[] RequiredUsings =
+ {
"OmniSharp.Extensions.LanguageServer.Protocol",
"OmniSharp.Extensions.LanguageServer.Protocol.Serialization",
"OmniSharp.Extensions.LanguageServer.Protocol.Server.Capabilities",
};
- protected override void Execute(
- GeneratorExecutionContext context, SyntaxReceiver syntaxReceiver, AddCacheSource addCacheSource,
- ReportCacheDiagnostic cacheDiagnostic
- )
+ private record AttributeData(
+ INamedTypeSymbol RegistrationOptionsInterfaceSymbol, INamedTypeSymbol TextDocumentRegistrationOptionsInterfaceSymbol,
+ INamedTypeSymbol WorkDoneProgressOptionsInterfaceSymbol, INamedTypeSymbol StaticRegistrationOptionsInterfaceSymbol
+ );
+ public void Initialize(IncrementalGeneratorInitializationContext context)
{
- var compilation = context.Compilation;
-
- var registrationOptionsInterfaceSymbol = compilation.GetTypeByMetadataName("OmniSharp.Extensions.LanguageServer.Protocol.IRegistrationOptions")!;
- var textDocumentRegistrationOptionsInterfaceSymbol =
- compilation.GetTypeByMetadataName("OmniSharp.Extensions.LanguageServer.Protocol.Models.ITextDocumentRegistrationOptions")!;
- var workDoneProgressOptionsInterfaceSymbol = compilation.GetTypeByMetadataName("OmniSharp.Extensions.LanguageServer.Protocol.Models.IWorkDoneProgressOptions")!;
- var staticRegistrationOptionsInterfaceSymbol = compilation.GetTypeByMetadataName("OmniSharp.Extensions.LanguageServer.Protocol.Models.IStaticRegistrationOptions")!;
+ var attributes = context.CompilationProvider
+ .Select(
+ (compilation, token) =>
+ {
+ var registrationOptionsInterfaceSymbol =
+ compilation.GetTypeByMetadataName("OmniSharp.Extensions.LanguageServer.Protocol.IRegistrationOptions")!;
+ var textDocumentRegistrationOptionsInterfaceSymbol =
+ compilation.GetTypeByMetadataName(
+ "OmniSharp.Extensions.LanguageServer.Protocol.Models.ITextDocumentRegistrationOptions"
+ )!;
+ var workDoneProgressOptionsInterfaceSymbol =
+ compilation.GetTypeByMetadataName(
+ "OmniSharp.Extensions.LanguageServer.Protocol.Models.IWorkDoneProgressOptions"
+ )!;
+ var staticRegistrationOptionsInterfaceSymbol =
+ compilation.GetTypeByMetadataName(
+ "OmniSharp.Extensions.LanguageServer.Protocol.Models.IStaticRegistrationOptions"
+ )!;
+ return new AttributeData(
+ registrationOptionsInterfaceSymbol, textDocumentRegistrationOptionsInterfaceSymbol,
+ workDoneProgressOptionsInterfaceSymbol, staticRegistrationOptionsInterfaceSymbol
+ );
+ }
+ );
+ var syntaxProvider = context.SyntaxProvider.CreateSyntaxProvider(
+ predicate: (syntaxNode, token) =>
+ syntaxNode is TypeDeclarationSyntax tds and (ClassDeclarationSyntax or RecordDeclarationSyntax)
+ && tds.AttributeLists
+ .SelectMany(z => z.Attributes)
+ .Any(z => z.Name.ToFullString().Contains("GenerateRegistrationOptions")),
+ (syntaxContext, token) => syntaxContext
+ )
+ .Combine(context.CompilationProvider)
+ .Select(
+ (tuple, token) =>
+ {
+ var (syntaxContext, compilation) = tuple;
+ var typeSymbol = syntaxContext.SemanticModel.GetDeclaredSymbol((TypeDeclarationSyntax)syntaxContext.Node);
+ if (typeSymbol is not { }) return default!;
+ var data = RegistrationOptionAttributes.Parse(
+ compilation,
+ (TypeDeclarationSyntax)syntaxContext.Node,
+ typeSymbol
+ );
+ return data is not { }
+ ? default!
+ : ( registrationOptions: (TypeDeclarationSyntax)syntaxContext.Node,
+ semanticModel: syntaxContext.SemanticModel, typeSymbol: typeSymbol, data: data! );
+ }
+ )
+ .Where(z => z is { data: { } })
+ .Combine(attributes)
+ .Select(
+ (tuple, token) => (
+ tuple.Left.registrationOptions, tuple.Left.data, tuple.Left.semanticModel, tuple.Left.typeSymbol,
+ attributes: tuple.Right )
+ )
+ ;
+
+ context.RegisterSourceOutput(syntaxProvider, GenerateRegistrationOptions);
+ context.RegisterSourceOutput(
+ syntaxProvider
+ .Select(
+ (tuple, token) => ( namespaces: tuple.typeSymbol.ContainingNamespace.ToDisplayString(),
+ AttributeArgument(TypeOfExpression(IdentifierName(tuple.typeSymbol.Name))) )
+ )
+ .Collect(), GenerateAssemblyRegistrationOptions
+ );
+ }
- foreach (var registrationOptions in syntaxReceiver.RegistrationOptions)
+ private void GenerateRegistrationOptions(
+ SourceProductionContext context,
+ (TypeDeclarationSyntax registrationOptions, RegistrationOptionAttributes data, SemanticModel semanticModel, INamedTypeSymbol typeSymbol,
+ AttributeData attributes) valueTuple
+ )
+ {
+ var (registrationOptions, data, semanticModel, typeSymbol, attributes) = valueTuple;
+ try
{
- try
+ if (!registrationOptions.Modifiers.Any(z => z.IsKind(SyntaxKind.PartialKeyword)))
{
- var semanticModel = context.Compilation.GetSemanticModel(registrationOptions.SyntaxTree);
- var typeSymbol = semanticModel.GetDeclaredSymbol(registrationOptions);
+ context.ReportDiagnostic(
+ Diagnostic.Create(GeneratorDiagnostics.MustBePartial, registrationOptions.Identifier.GetLocation(), registrationOptions.Identifier.Text)
+ );
+ return;
+ }
- if (typeSymbol is not { }) continue;
- var data = RegistrationOptionAttributes.Parse(context, registrationOptions, typeSymbol);
- if (data is not { }) continue;
+ var extendedRegistrationOptions = registrationOptions.WithAttributeLists(List())
+ .WithBaseList(
+ BaseList(
+ SingletonSeparatedList(
+ SimpleBaseType(
+ ParseName(attributes.RegistrationOptionsInterfaceSymbol.ToDisplayString())
+ )
+ )
+ )
+ )
+ .WithMembers(List());
- if (!registrationOptions.Modifiers.Any(z => z.IsKind(SyntaxKind.PartialKeyword)))
- {
- cacheDiagnostic(registrationOptions, static r => Diagnostic.Create(GeneratorDiagnostics.MustBePartial, r.Identifier.GetLocation(), r.Identifier.Text));
- continue;
- }
- var extendedRegistrationOptions = registrationOptions
- .WithAttributeLists(List())
- .WithBaseList(
- BaseList(
- SingletonSeparatedList(
- SimpleBaseType(ParseName(registrationOptionsInterfaceSymbol.ToDisplayString()))
- )
- )
- )
- .WithMembers(List());
-
-
- var staticRegistrationOptions = registrationOptions
- .WithIdentifier(Identifier($"StaticOptions"))
- .WithMembers(List(registrationOptions.Members.OfType()))
- .WithAttributeLists(List());
-
- var staticBaseList =
- registrationOptions.BaseList?.Types.Where(z => z.Type.GetSyntaxName() != textDocumentRegistrationOptionsInterfaceSymbol.Name).ToArray()
- ?? Array.Empty();
- if (staticBaseList.Length > 0)
- {
- staticRegistrationOptions = staticRegistrationOptions.WithBaseList(BaseList(SeparatedList(staticBaseList)));
- }
- else
+ var staticRegistrationOptions = registrationOptions.WithIdentifier(Identifier($"StaticOptions"))
+ .WithMembers(
+ List(
+ registrationOptions.Members.OfType()
+ )
+ )
+ .WithAttributeLists(List());
+
+ var staticBaseList =
+ registrationOptions.BaseList?.Types.Where(z => z.Type.GetSyntaxName() != attributes.TextDocumentRegistrationOptionsInterfaceSymbol.Name)
+ .ToArray() ?? Array.Empty();
+ if (staticBaseList.Length > 0)
+ {
+ staticRegistrationOptions = staticRegistrationOptions.WithBaseList(BaseList(SeparatedList(staticBaseList)));
+ }
+ else
+ {
+ staticRegistrationOptions = staticRegistrationOptions.WithBaseList(null);
+ }
+
+ if (data.KeyExpression is { })
+ {
+ var attributeList = AttributeList(
+ SingletonSeparatedList(
+ Attribute(
+ IdentifierName("RegistrationOptionsKey"), AttributeArgumentList(SeparatedList(data.KeyExpression.Select(AttributeArgument)))
+ )
+ )
+ );
+ extendedRegistrationOptions = extendedRegistrationOptions.AddAttributeLists(attributeList);
+ staticRegistrationOptions = staticRegistrationOptions.AddAttributeLists(attributeList);
+ }
+
+ if (data.SupportsDocumentSelector && !data.ImplementsDocumentSelector)
+ {
+ if (registrationOptions.BaseList?.Types.Any(
+ z => z.Type.ToFullString().Contains(attributes.TextDocumentRegistrationOptionsInterfaceSymbol.Name)
+ ) != true)
{
- staticRegistrationOptions = staticRegistrationOptions.WithBaseList(null);
+ extendedRegistrationOptions = ExtendAndImplementInterface(
+ extendedRegistrationOptions, attributes.TextDocumentRegistrationOptionsInterfaceSymbol
+ );
}
- if (data.KeyExpression is { })
- {
- var attributeList =
- AttributeList(
- SingletonSeparatedList(
- Attribute(
- IdentifierName("RegistrationOptionsKey"),
- AttributeArgumentList(
- SeparatedList(data.KeyExpression.Select(AttributeArgument))
- )
+ extendedRegistrationOptions = extendedRegistrationOptions.AddMembers(
+ PropertyDeclaration(NullableType(IdentifierName("DocumentSelector")), 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))
+ }
)
)
- );
- extendedRegistrationOptions = extendedRegistrationOptions.AddAttributeLists(attributeList);
- staticRegistrationOptions = staticRegistrationOptions.AddAttributeLists(attributeList);
- }
+ )
+ );
+ }
- if (data.SupportsDocumentSelector && !data.ImplementsDocumentSelector)
+ if (data.SupportsWorkDoneProgress && !data.ImplementsWorkDoneProgress)
+ {
+ if (registrationOptions.BaseList?.Types.Any(z => z.Type.GetSyntaxName() == attributes.WorkDoneProgressOptionsInterfaceSymbol.Name) != true)
{
- if (registrationOptions.BaseList?.Types.Any(z => z.Type.ToFullString().Contains(textDocumentRegistrationOptionsInterfaceSymbol.Name)) != true)
- {
- extendedRegistrationOptions = ExtendAndImplementInterface(extendedRegistrationOptions, textDocumentRegistrationOptionsInterfaceSymbol);
- }
-
- extendedRegistrationOptions = extendedRegistrationOptions
- .AddMembers(
- PropertyDeclaration(NullableType(IdentifierName("DocumentSelector")), 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))
- }
- )
- )
- )
- );
+ extendedRegistrationOptions = ExtendAndImplementInterface(
+ extendedRegistrationOptions, attributes.WorkDoneProgressOptionsInterfaceSymbol
+ );
+ staticRegistrationOptions = ExtendAndImplementInterface(staticRegistrationOptions, attributes.WorkDoneProgressOptionsInterfaceSymbol);
}
- if (data.SupportsWorkDoneProgress && !data.ImplementsWorkDoneProgress)
- {
- if (registrationOptions.BaseList?.Types.Any(z => z.Type.GetSyntaxName() == workDoneProgressOptionsInterfaceSymbol.Name) != true)
- {
- extendedRegistrationOptions = ExtendAndImplementInterface(extendedRegistrationOptions, workDoneProgressOptionsInterfaceSymbol);
- staticRegistrationOptions = ExtendAndImplementInterface(staticRegistrationOptions, workDoneProgressOptionsInterfaceSymbol);
- }
-
- staticRegistrationOptions = staticRegistrationOptions.AddMembers(GetWorkDoneProperty());
- extendedRegistrationOptions = extendedRegistrationOptions.AddMembers(GetWorkDoneProperty());
- }
+ staticRegistrationOptions = staticRegistrationOptions.AddMembers(GetWorkDoneProperty());
+ extendedRegistrationOptions = extendedRegistrationOptions.AddMembers(GetWorkDoneProperty());
+ }
- if (data.SupportsStaticRegistrationOptions && !data.ImplementsStaticRegistrationOptions)
+ if (data.SupportsStaticRegistrationOptions && !data.ImplementsStaticRegistrationOptions)
+ {
+ if (registrationOptions.BaseList?.Types.Any(z => z.Type.GetSyntaxName() == attributes.StaticRegistrationOptionsInterfaceSymbol.Name)
+ != true)
{
- if (registrationOptions.BaseList?.Types.Any(z => z.Type.GetSyntaxName() == staticRegistrationOptionsInterfaceSymbol.Name) != true)
- {
- extendedRegistrationOptions = ExtendAndImplementInterface(extendedRegistrationOptions, staticRegistrationOptionsInterfaceSymbol);
- staticRegistrationOptions = ExtendAndImplementInterface(staticRegistrationOptions, staticRegistrationOptionsInterfaceSymbol);
- }
-
- staticRegistrationOptions = staticRegistrationOptions.AddMembers(GetIdProperty());
- extendedRegistrationOptions = extendedRegistrationOptions.AddMembers(GetIdProperty());
+ extendedRegistrationOptions = ExtendAndImplementInterface(
+ extendedRegistrationOptions, attributes.StaticRegistrationOptionsInterfaceSymbol
+ );
+ staticRegistrationOptions = ExtendAndImplementInterface(staticRegistrationOptions, attributes.StaticRegistrationOptionsInterfaceSymbol);
}
- if (data.RegistrationOptionsConverter is null
- && CreateConverter(registrationOptions, staticRegistrationOptions.Members.OfType()) is { } converter)
- {
- extendedRegistrationOptions = extendedRegistrationOptions
- .AddAttributeLists(
- AttributeList(
- SingletonSeparatedList(
- Attribute(
- IdentifierName("RegistrationOptionsConverterAttribute"),
- AttributeArgumentList(
- SingletonSeparatedList(
- AttributeArgument(
- TypeOfExpression(IdentifierName(converter.Identifier.Text))
+ staticRegistrationOptions = staticRegistrationOptions.AddMembers(GetIdProperty());
+ extendedRegistrationOptions = extendedRegistrationOptions.AddMembers(GetIdProperty());
+ }
+
+ if (data.RegistrationOptionsConverter is null && CreateConverter(
+ registrationOptions, staticRegistrationOptions.Members.OfType()
+ ) is { } converter)
+ {
+ extendedRegistrationOptions = extendedRegistrationOptions.AddAttributeLists(
+ AttributeList(
+ SingletonSeparatedList(
+ Attribute(
+ IdentifierName("RegistrationOptionsConverterAttribute"),
+ AttributeArgumentList(
+ SingletonSeparatedList(
+ AttributeArgument(
+ TypeOfExpression(
+ IdentifierName(converter.Identifier.Text)
+ )
+ )
+ )
+ )
+ )
+ )
+ )
)
- )
- )
- )
- )
- )
- )
- .AddMembers(converter);
- }
+ .AddMembers(converter);
+ }
- extendedRegistrationOptions = extendedRegistrationOptions.AddMembers(staticRegistrationOptions);
+ extendedRegistrationOptions = extendedRegistrationOptions.AddMembers(staticRegistrationOptions);
- var members = new List() { extendedRegistrationOptions };
+ var members = new List() { extendedRegistrationOptions };
- var cu = CompilationUnit()
- .WithUsings(registrationOptions.SyntaxTree.GetCompilationUnitRoot().Usings)
- .AddMembers(
- NamespaceDeclaration(ParseName(typeSymbol.ContainingNamespace.ToDisplayString()))
- .WithMembers(List(members))
- .WithLeadingTrivia(TriviaList(Trivia(NullableDirectiveTrivia(Token(SyntaxKind.EnableKeyword), true))))
- .WithTrailingTrivia(TriviaList(Trivia(NullableDirectiveTrivia(Token(SyntaxKind.RestoreKeyword), true))))
- )
- .WithLeadingTrivia(Comment(Preamble.GeneratedByATool))
- .WithTrailingTrivia(CarriageReturnLineFeed);
+ var cu = CompilationUnit()
+ .WithUsings(registrationOptions.SyntaxTree.GetCompilationUnitRoot().Usings)
+ .AddMembers(
+ NamespaceDeclaration(ParseName(typeSymbol.ContainingNamespace.ToDisplayString()))
+ .WithMembers(List(members))
+ .WithLeadingTrivia(TriviaList(Trivia(NullableDirectiveTrivia(Token(SyntaxKind.EnableKeyword), true))))
+ .WithTrailingTrivia(TriviaList(Trivia(NullableDirectiveTrivia(Token(SyntaxKind.RestoreKeyword), true))))
+ );
- foreach (var ns in RequiredUsings)
+ foreach (var ns in RequiredUsings)
+ {
+ if (cu.Usings.All(z => z.Name.ToFullString() != ns))
{
- if (cu.Usings.All(z => z.Name.ToFullString() != ns))
- {
- cu = cu.AddUsings(UsingDirective(ParseName(ns)));
- }
+ cu = cu.AddUsings(UsingDirective(ParseName(ns)));
}
-
- addCacheSource(
- $"{registrationOptions.Identifier.Text}.cs",
- registrationOptions,
- cu.NormalizeWhitespace().GetText(Encoding.UTF8)
- );
- }
- catch (Exception e)
- {
- context.ReportDiagnostic(Diagnostic.Create(GeneratorDiagnostics.Exception, registrationOptions.GetLocation(), e.Message, e.StackTrace ?? string.Empty));
- Debug.WriteLine(e);
- Debug.WriteLine(e.StackTrace);
}
+
+ context.AddSource($"{registrationOptions.Identifier.Text}.cs", cu.NormalizeWhitespace().GetText(Encoding.UTF8));
+ }
+ catch (Exception e)
+ {
+ context.ReportDiagnostic(
+ Diagnostic.Create(GeneratorDiagnostics.Exception, registrationOptions.GetLocation(), e.Message, e.StackTrace ?? string.Empty)
+ );
+ Debug.WriteLine(e);
+ Debug.WriteLine(e.StackTrace);
}
+ }
+ private void GenerateAssemblyRegistrationOptions(
+ SourceProductionContext context, ImmutableArray<(string @namespace, AttributeArgumentSyntax argumentSyntax)> types
+ )
+ {
+ var namespaces = new HashSet() { "OmniSharp.Extensions.LanguageServer.Protocol" };
+ if (types.Any())
{
- var namespaces = new HashSet() { "OmniSharp.Extensions.LanguageServer.Protocol" };
- var types = syntaxReceiver.FoundNodes
- .Concat(syntaxReceiver.RegistrationOptions)
- .Select(
- options => {
- var semanticModel = context.Compilation.GetSemanticModel(options.SyntaxTree);
- var typeSymbol = semanticModel.GetDeclaredSymbol(options)!;
- namespaces.Add(typeSymbol.ContainingNamespace.ToDisplayString());
- return AttributeArgument(TypeOfExpression(IdentifierName(typeSymbol.Name)));
- }
- )
- .ToArray();
- if (types.Any())
+ foreach (var item in types)
{
- var cu = CompilationUnit()
- .WithUsings(List(namespaces.OrderBy(z => z).Select(z => UsingDirective(ParseName(z)))))
- .AddAttributeLists(
- AttributeList(
- target: AttributeTargetSpecifier(Token(SyntaxKind.AssemblyKeyword)),
- SingletonSeparatedList(Attribute(IdentifierName("AssemblyRegistrationOptions"), AttributeArgumentList(SeparatedList(types))))
+ namespaces.Add(item.@namespace);
+ }
+
+ var cu = CompilationUnit()
+ .WithUsings(List(namespaces.OrderBy(z => z).Select(z => UsingDirective(ParseName(z)))))
+ .AddAttributeLists(
+ AttributeList(
+ target: AttributeTargetSpecifier(Token(SyntaxKind.AssemblyKeyword)),
+ SingletonSeparatedList(
+ Attribute(
+ IdentifierName("AssemblyRegistrationOptions"),
+ AttributeArgumentList(SeparatedList(types.Select(z => z.argumentSyntax)))
+ )
)
)
- .WithLeadingTrivia(Comment(Preamble.GeneratedByATool))
- .WithTrailingTrivia(CarriageReturnLineFeed);
+ );
- context.AddSource("AssemblyRegistrationOptions.cs", cu.NormalizeWhitespace().GetText(Encoding.UTF8));
- }
+ context.AddSource("AssemblyRegistrationOptions.cs", cu.NormalizeWhitespace().GetText(Encoding.UTF8));
}
+ }
- static TypeDeclarationSyntax ExtendAndImplementInterface(TypeDeclarationSyntax syntax, ITypeSymbol symbolToExtendFrom)
- {
- return syntax switch {
- ClassDeclarationSyntax cd => cd.AddBaseListTypes(SimpleBaseType(ParseName(symbolToExtendFrom.ToDisplayString()))),
- RecordDeclarationSyntax rd => rd.AddBaseListTypes(SimpleBaseType(ParseName(symbolToExtendFrom.ToDisplayString()))),
- _ => throw new NotSupportedException()
- };
- }
- static PropertyDeclarationSyntax GetWorkDoneProperty()
+ static TypeDeclarationSyntax ExtendAndImplementInterface(TypeDeclarationSyntax syntax, ITypeSymbol symbolToExtendFrom)
+ {
+ return syntax switch
{
- return PropertyDeclaration(PredefinedType(Token(SyntaxKind.BoolKeyword)), Identifier("WorkDoneProgress"))
- .WithModifiers(TokenList(Token(SyntaxKind.PublicKeyword)))
- .WithAttributeLists(
- SingletonList(
- AttributeList(
- SingletonSeparatedList(Attribute(IdentifierName("Optional")))
- )
+ ClassDeclarationSyntax cd => cd.AddBaseListTypes(SimpleBaseType(ParseName(symbolToExtendFrom.ToDisplayString()))),
+ RecordDeclarationSyntax rd => rd.AddBaseListTypes(SimpleBaseType(ParseName(symbolToExtendFrom.ToDisplayString()))),
+ _ => throw new NotSupportedException()
+ };
+ }
+
+ static PropertyDeclarationSyntax GetWorkDoneProperty()
+ {
+ return PropertyDeclaration(PredefinedType(Token(SyntaxKind.BoolKeyword)), Identifier("WorkDoneProgress"))
+ .WithModifiers(TokenList(Token(SyntaxKind.PublicKeyword)))
+ .WithAttributeLists(
+ SingletonList(
+ AttributeList(
+ SingletonSeparatedList(Attribute(IdentifierName("Optional")))
)
)
- .WithAccessorList(CommonElements.GetSetAccessor);
- }
+ )
+ .WithAccessorList(CommonElements.GetSetAccessor);
+ }
- static PropertyDeclarationSyntax GetIdProperty()
- {
- return PropertyDeclaration(NullableType(PredefinedType(Token(SyntaxKind.StringKeyword))), Identifier("Id"))
- .WithModifiers(TokenList(Token(SyntaxKind.PublicKeyword)))
- .WithAttributeLists(
- SingletonList(
- AttributeList(
- SingletonSeparatedList(Attribute(IdentifierName("Optional")))
- )
+ static PropertyDeclarationSyntax GetIdProperty()
+ {
+ return PropertyDeclaration(NullableType(PredefinedType(Token(SyntaxKind.StringKeyword))), Identifier("Id"))
+ .WithModifiers(TokenList(Token(SyntaxKind.PublicKeyword)))
+ .WithAttributeLists(
+ SingletonList(
+ AttributeList(
+ SingletonSeparatedList(Attribute(IdentifierName("Optional")))
)
)
- .WithAccessorList(CommonElements.GetSetAccessor);
- }
+ )
+ .WithAccessorList(CommonElements.GetSetAccessor);
}
private static IEnumerable GetMapping(IEnumerable properties, IdentifierNameSyntax paramName)
{
return properties
- .Where(z => z.AccessorList?.Accessors.Any(a => a.Keyword.Kind() == SyntaxKind.SetKeyword || a.Keyword.Kind() == SyntaxKind.InitKeyword) == true)
+ .Where(
+ z => z.AccessorList?.Accessors.Any(a => a.Keyword.Kind() == SyntaxKind.SetKeyword || a.Keyword.Kind() == SyntaxKind.InitKeyword) == true
+ )
.Select(
property => AssignmentExpression(
SyntaxKind.SimpleAssignmentExpression,
@@ -310,7 +384,8 @@ private static IEnumerable GetMapping(IEnumerable GetMapping(IEnumerable GetMapping(IEnumerable new SyntaxReceiver(Cache))
- {
- }
-
- public static CacheContainer Cache = new();
-
- public class SyntaxReceiver : SyntaxReceiverCache
- {
- public List RegistrationOptions { get; } = new();
-
- public override string? GetKey(TypeDeclarationSyntax syntax)
- {
- var hasher = new CacheKeyHasher();
- hasher.Append(syntax.SyntaxTree.FilePath);
- hasher.Append(syntax.Keyword.Text);
- hasher.Append(syntax.Identifier.Text);
- hasher.Append(syntax.TypeParameterList);
- hasher.Append(syntax.AttributeLists);
- hasher.Append(syntax.BaseList);
- foreach (var item in syntax.Members.OfType().Select(z => z.Identifier.Text))
- {
- hasher.Append(item);
- }
-
- return hasher;
- }
-
- ///
- /// Called for every syntax node in the compilation, we can inspect the nodes and save any information useful for generation
- ///
- public override void OnVisitNode(TypeDeclarationSyntax syntaxNode)
- {
- if (syntaxNode is ClassDeclarationSyntax or RecordDeclarationSyntax
- && syntaxNode.AttributeLists
- .SelectMany(z => z.Attributes)
- .Any(z => z.Name.ToFullString().Contains("GenerateRegistrationOptions"))
- )
- {
- RegistrationOptions.Add(syntaxNode);
- }
- }
-
- public SyntaxReceiver(CacheContainer cache) : base(cache)
- {
- }
- }
}
}
diff --git a/src/JsonRpc.Generators/Strategies/EnsureNamespaceStrategy.cs b/src/JsonRpc.Generators/Strategies/EnsureNamespaceStrategy.cs
index 7f4482cde..76e48e5b7 100644
--- a/src/JsonRpc.Generators/Strategies/EnsureNamespaceStrategy.cs
+++ b/src/JsonRpc.Generators/Strategies/EnsureNamespaceStrategy.cs
@@ -1,4 +1,5 @@
using System.Collections.Generic;
+using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using OmniSharp.Extensions.JsonRpc.Generators.Contexts;
@@ -6,7 +7,7 @@ namespace OmniSharp.Extensions.JsonRpc.Generators.Strategies
{
internal class EnsureNamespaceStrategy : IExtensionMethodGeneratorStrategy
{
- public IEnumerable Apply(GeneratorData item)
+ public IEnumerable Apply(SourceProductionContext context, GeneratorData item)
{
if (item.Capability != null) item.AdditionalUsings.Add(item.Capability.Symbol.ContainingNamespace.ToDisplayString());
if (item.RegistrationOptions != null) item.AdditionalUsings.Add(item.RegistrationOptions.Symbol.ContainingNamespace.ToDisplayString());
diff --git a/src/JsonRpc.Generators/Strategies/ExtensionMethodGeneratorStrategy.cs b/src/JsonRpc.Generators/Strategies/ExtensionMethodGeneratorStrategy.cs
index 0b8116e80..182210655 100644
--- a/src/JsonRpc.Generators/Strategies/ExtensionMethodGeneratorStrategy.cs
+++ b/src/JsonRpc.Generators/Strategies/ExtensionMethodGeneratorStrategy.cs
@@ -19,13 +19,13 @@ public ExtensionMethodGeneratorStrategy(ImmutableArray Apply(GeneratorData item)
+ public IEnumerable Apply(SourceProductionContext context, GeneratorData item)
{
var methods = _extensionMethodGeneratorStrategies.Aggregate(
new List(), (m, strategy) => {
try
{
- m.AddRange(strategy.Apply(item));
+ m.AddRange(strategy.Apply(context, item));
}
catch (Exception e)
{
diff --git a/src/JsonRpc.Generators/Strategies/HandlerGeneratorStrategy.cs b/src/JsonRpc.Generators/Strategies/HandlerGeneratorStrategy.cs
index 65881c524..08a0b1368 100644
--- a/src/JsonRpc.Generators/Strategies/HandlerGeneratorStrategy.cs
+++ b/src/JsonRpc.Generators/Strategies/HandlerGeneratorStrategy.cs
@@ -11,7 +11,7 @@ namespace OmniSharp.Extensions.JsonRpc.Generators.Strategies
{
internal class HandlerGeneratorStrategy : ICompilationUnitGeneratorStrategy
{
- public IEnumerable Apply(GeneratorData item)
+ public IEnumerable Apply(SourceProductionContext context, GeneratorData item)
{
if (item.JsonRpcAttributes.GenerateHandler is not { }) yield break;
var members = new List();
diff --git a/src/JsonRpc.Generators/Strategies/HandlerRegistryActionContextRunnerStrategy.cs b/src/JsonRpc.Generators/Strategies/HandlerRegistryActionContextRunnerStrategy.cs
index ffda7747c..ab5ddf6df 100644
--- a/src/JsonRpc.Generators/Strategies/HandlerRegistryActionContextRunnerStrategy.cs
+++ b/src/JsonRpc.Generators/Strategies/HandlerRegistryActionContextRunnerStrategy.cs
@@ -1,6 +1,7 @@
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
+using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using OmniSharp.Extensions.JsonRpc.Generators.Contexts;
@@ -14,17 +15,20 @@ public HandlerRegistryActionContextRunnerStrategy(ImmutableArray Apply(GeneratorData item)
+ public IEnumerable Apply(SourceProductionContext context, GeneratorData item)
{
+ foreach (var diagnostic in item.JsonRpcAttributes.HandlerRegistryDiagnostics)
+ {
+ context.ReportDiagnostic(diagnostic);
+ }
return item.JsonRpcAttributes.HandlerRegistries
.Select(
registry => new ExtensionMethodContext(
- item.JsonRpcAttributes.GenerateHandlerMethods!.Data, item.TypeDeclaration, item.TypeSymbol, registry, item.JsonRpcAttributes.HandlerRegistries,
- item.Context
+ item.JsonRpcAttributes.GenerateHandlerMethods!.Data, item.TypeDeclaration, item.TypeSymbol, registry, item.JsonRpcAttributes.HandlerRegistries
) { IsRegistry = true }
)
.SelectMany(_ => _strategies, (actionContext, strategy) => new { actionContext, strategy })
- .SelectMany(@t => @t.strategy.Apply(@t.actionContext, item));
+ .SelectMany(@t => @t.strategy.Apply(context, @t.actionContext, item));
}
}
}
diff --git a/src/JsonRpc.Generators/Strategies/OnNotificationMethodGeneratorWithRegistrationOptionsStrategy.cs b/src/JsonRpc.Generators/Strategies/OnNotificationMethodGeneratorWithRegistrationOptionsStrategy.cs
index 660226913..b4f0324bc 100644
--- a/src/JsonRpc.Generators/Strategies/OnNotificationMethodGeneratorWithRegistrationOptionsStrategy.cs
+++ b/src/JsonRpc.Generators/Strategies/OnNotificationMethodGeneratorWithRegistrationOptionsStrategy.cs
@@ -2,6 +2,7 @@
using System.Linq;
using System.Collections.Generic;
using System.Collections.Immutable;
+using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using OmniSharp.Extensions.JsonRpc.Generators.Contexts;
@@ -13,7 +14,7 @@ namespace OmniSharp.Extensions.JsonRpc.Generators.Strategies
{
internal class OnNotificationMethodGeneratorWithRegistrationOptionsStrategy : IExtensionMethodContextGeneratorStrategy
{
- public IEnumerable Apply(ExtensionMethodContext extensionMethodContext, GeneratorData item)
+ public IEnumerable Apply(SourceProductionContext context, ExtensionMethodContext extensionMethodContext, GeneratorData item)
{
if (item is not { RegistrationOptions: { } registrationOptions }) yield break;
if (item is not NotificationItem notification) yield break;
diff --git a/src/JsonRpc.Generators/Strategies/OnNotificationMethodGeneratorWithoutRegistrationOptionsStrategy.cs b/src/JsonRpc.Generators/Strategies/OnNotificationMethodGeneratorWithoutRegistrationOptionsStrategy.cs
index 984cf5f4b..d0e158e53 100644
--- a/src/JsonRpc.Generators/Strategies/OnNotificationMethodGeneratorWithoutRegistrationOptionsStrategy.cs
+++ b/src/JsonRpc.Generators/Strategies/OnNotificationMethodGeneratorWithoutRegistrationOptionsStrategy.cs
@@ -1,4 +1,5 @@
using System.Collections.Generic;
+using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using OmniSharp.Extensions.JsonRpc.Generators.Contexts;
@@ -10,7 +11,7 @@ namespace OmniSharp.Extensions.JsonRpc.Generators.Strategies
{
internal class OnNotificationMethodGeneratorWithoutRegistrationOptionsStrategy : IExtensionMethodContextGeneratorStrategy
{
- public IEnumerable