From 740ed653f79bc0f4c2f558aa42dfdc3d816fe907 Mon Sep 17 00:00:00 2001 From: Claire Novotny Date: Tue, 30 Nov 2021 11:01:31 -0500 Subject: [PATCH 1/2] Add sample with source generator showing Roslyn 3.8 & 4.0 along with packing --- SourceGeneratorExample/.editorconfig | 254 ++++++++++++++++++ SourceGeneratorExample/Directory.Build.props | 10 + .../SourceGeneratorExample.Roslyn38.csproj | 20 ++ .../SourceGeneratorExample.Roslyn40.csproj | 21 ++ .../SourceGeneratorExample.cs | 123 +++++++++ .../SourceGeneratorExample.sln | 85 ++++++ .../SourceGeneratorExample.csproj | 33 +++ .../targets/SourceGeneratorExample.props | 7 + .../targets/SourceGeneratorExample.targets | 57 ++++ SourceGeneratorExample/key.snk | Bin 0 -> 596 bytes 10 files changed, 610 insertions(+) create mode 100644 SourceGeneratorExample/.editorconfig create mode 100644 SourceGeneratorExample/Directory.Build.props create mode 100644 SourceGeneratorExample/SourceGeneratorExample.Roslyn38/SourceGeneratorExample.Roslyn38.csproj create mode 100644 SourceGeneratorExample/SourceGeneratorExample.Roslyn40/SourceGeneratorExample.Roslyn40.csproj create mode 100644 SourceGeneratorExample/SourceGeneratorExample.Shared/SourceGeneratorExample.cs create mode 100644 SourceGeneratorExample/SourceGeneratorExample.sln create mode 100644 SourceGeneratorExample/SourceGeneratorExample/SourceGeneratorExample.csproj create mode 100644 SourceGeneratorExample/SourceGeneratorExample/targets/SourceGeneratorExample.props create mode 100644 SourceGeneratorExample/SourceGeneratorExample/targets/SourceGeneratorExample.targets create mode 100644 SourceGeneratorExample/key.snk diff --git a/SourceGeneratorExample/.editorconfig b/SourceGeneratorExample/.editorconfig new file mode 100644 index 0000000..86c189a --- /dev/null +++ b/SourceGeneratorExample/.editorconfig @@ -0,0 +1,254 @@ +# EditorConfig is awesome:http://EditorConfig.org +# From https://raw.githubusercontent.com/dotnet/roslyn/master/.editorconfig + +# top-most EditorConfig file +root = true + +# Don't use tabs for indentation. +[*] +indent_style = space +trim_trailing_whitespace = true +# (Please don't specify an indent_size here; that has too many unintended consequences.) + +# Code files +[*.{cs,csx,vb,vbx}] +indent_size = 4 +insert_final_newline = true +charset = utf-8-bom + +# Xml project files +[*.{csproj,vbproj,vcxproj,vcxproj.filters,proj,projitems,shproj}] +indent_size = 2 + +# Xml config files +[*.{props,targets,ruleset,config,nuspec,resx,vsixmanifest,vsct}] +indent_size = 2 + +# Yml/Yaml files +[*.{yaml,yml}] +indent_size = 2 + +# Powershell files +[*.ps1] +indent_size = 2 + +# JSON files +[*.json] +indent_size = 2 + +# Shell scripts +[*.sh] +end_of_line = lf + +[*.{cmd,bat}] +end_of_line = crlf + +# Dotnet code style settings: +[*.{cs,vb}] +# Sort using and Import directives with System.* appearing first +dotnet_sort_system_directives_first = true +# Put a blank line between System.* and Microsoft.* +dotnet_separate_import_directive_groups = true + +# Avoid "this." and "Me." if not necessary +dotnet_style_qualification_for_field = false:suggestion +dotnet_style_qualification_for_property = false:suggestion +dotnet_style_qualification_for_method = false:suggestion +dotnet_style_qualification_for_event = false:suggestion + +# Use language keywords instead of framework type names for type references +dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion +dotnet_style_predefined_type_for_member_access = true:suggestion + +# Prefer read-only on fields +dotnet_style_readonly_field = true:warning + +# Suggest more modern language features when available +dotnet_style_object_initializer = true:suggestion +dotnet_style_collection_initializer = true:suggestion +dotnet_style_coalesce_expression = true:suggestion +dotnet_style_null_propagation = true:suggestion +dotnet_style_explicit_tuple_names = true:suggestion +dotnet_style_prefer_inferred_tuple_names = true:suggestion +dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion +dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion +dotnet_style_prefer_conditional_expression_over_return = false +dotnet_style_prefer_conditional_expression_over_assignment = false +dotnet_style_prefer_auto_properties = true:suggestion + +# Parentheses +dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:silent +dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:silent +dotnet_style_parentheses_in_other_operators = never_if_unnecessary:silent +dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:silent + +# Accessibility modifiers +dotnet_style_require_accessibility_modifiers = omit_if_default:suggestion + + +# Naming Rules + +# Interfaces start with an I and are PascalCased +dotnet_naming_rule.interfaces_must_be_pascal_cased_and_prefixed_with_I.symbols = interface_symbols +dotnet_naming_rule.interfaces_must_be_pascal_cased_and_prefixed_with_I.style = pascal_case_and_prefix_with_I_style +dotnet_naming_rule.interfaces_must_be_pascal_cased_and_prefixed_with_I.severity = warning + +# External members are PascalCased +dotnet_naming_rule.externally_visible_members_must_be_pascal_cased.symbols = externally_visible_symbols +dotnet_naming_rule.externally_visible_members_must_be_pascal_cased.style = pascal_case_style +dotnet_naming_rule.externally_visible_members_must_be_pascal_cased.severity = warning + +# Parameters are camelCased +dotnet_naming_rule.parameters_must_be_camel_cased.symbols = parameter_symbols +dotnet_naming_rule.parameters_must_be_camel_cased.style = camel_case_style +dotnet_naming_rule.parameters_must_be_camel_cased.severity = warning + +# Constants are PascalCased +dotnet_naming_rule.constants_must_be_pascal_cased.symbols = constant_symbols +dotnet_naming_rule.constants_must_be_pascal_cased.style = pascal_case_style +dotnet_naming_rule.constants_must_be_pascal_cased.severity = warning + +# Uncomment this group and comment out the next group if you prefer s_ prefixes for static fields + +# Private static fields are prefixed with s_ and are camelCased like s_myStatic +#dotnet_naming_rule.private_static_fields_must_be_camel_cased_and_prefixed_with_s_underscore.symbols = private_static_field_symbols +#dotnet_naming_rule.private_static_fields_must_be_camel_cased_and_prefixed_with_s_underscore.style = camel_case_and_prefix_with_s_underscore_style +#dotnet_naming_rule.private_static_fields_must_be_camel_cased_and_prefixed_with_s_underscore.severity = warning + +# Static readonly fields are PascalCased +dotnet_naming_rule.static_readonly_fields_should_be_pascal_case.symbols = private_static_readonly_field_symbols +dotnet_naming_rule.static_readonly_fields_should_be_pascal_case.style = pascal_case_style +dotnet_naming_rule.static_readonly_fields_should_be_pascal_case.severity = warning + +# Comment this group and uncomment out the next group if you don't want _ prefixed fields. + +# Private instance fields are camelCased with an _ like _myField +#dotnet_naming_rule.private_instance_fields_must_be_camel_cased_and_prefixed_with_underscore.symbols = private_field_symbols +#dotnet_naming_rule.private_instance_fields_must_be_camel_cased_and_prefixed_with_underscore.style = camel_case_and_prefix_with_underscore_style +#dotnet_naming_rule.private_instance_fields_must_be_camel_cased_and_prefixed_with_underscore.severity = warning + +# Private instance fields are camelCased +dotnet_naming_rule.private_instance_fields_must_be_camel_cased.symbols = private_field_symbols +dotnet_naming_rule.private_instance_fields_must_be_camel_cased.style = camel_case_style +dotnet_naming_rule.private_instance_fields_must_be_camel_cased.severity = warning + +# Symbols +dotnet_naming_symbols.externally_visible_symbols.applicable_kinds = class,struct,interface,enum,property,method,field,event,delegate +dotnet_naming_symbols.externally_visible_symbols.applicable_accessibilities = public,internal,friend,protected,protected_internal,protected_friend,private_protected + +dotnet_naming_symbols.interface_symbols.applicable_kinds = interface +dotnet_naming_symbols.interface_symbols.applicable_accessibilities = * + +dotnet_naming_symbols.parameter_symbols.applicable_kinds = parameter +dotnet_naming_symbols.parameter_symbols.applicable_accessibilities = * + +dotnet_naming_symbols.constant_symbols.applicable_kinds = field +dotnet_naming_symbols.constant_symbols.required_modifiers = const +dotnet_naming_symbols.constant_symbols.applicable_accessibilities = * + +dotnet_naming_symbols.private_static_field_symbols.applicable_kinds = field +dotnet_naming_symbols.private_static_field_symbols.required_modifiers = static,shared +dotnet_naming_symbols.private_static_field_symbols.applicable_accessibilities = private + +dotnet_naming_symbols.private_static_readonly_field_symbols.applicable_kinds = field +dotnet_naming_symbols.private_static_readonly_field_symbols.required_modifiers = static,shared,readonly +dotnet_naming_symbols.private_static_readonly_field_symbols.applicable_accessibilities = private + +dotnet_naming_symbols.private_field_symbols.applicable_kinds = field +dotnet_naming_symbols.private_field_symbols.applicable_accessibilities = private + +# Styles +dotnet_naming_style.camel_case_style.capitalization = camel_case + +dotnet_naming_style.pascal_case_style.capitalization = pascal_case + +dotnet_naming_style.camel_case_and_prefix_with_s_underscore_style.required_prefix = s_ +dotnet_naming_style.camel_case_and_prefix_with_s_underscore_style.capitalization = camel_case + +dotnet_naming_style.camel_case_and_prefix_with_underscore_style.required_prefix = _ +dotnet_naming_style.camel_case_and_prefix_with_underscore_style.capitalization = camel_case + +dotnet_naming_style.pascal_case_and_prefix_with_I_style.required_prefix = I +dotnet_naming_style.pascal_case_and_prefix_with_I_style.capitalization = pascal_case + + +# CSharp code style settings: +[*.cs] +# Modifier order +csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:suggestion + +# Code block +csharp_prefer_braces = false:none + +# Indentation preferences +csharp_indent_block_contents = true +csharp_indent_braces = false +csharp_indent_case_contents = true +csharp_indent_switch_labels = true +csharp_indent_labels = flush_left + +# Prefer "var" everywhere +csharp_style_var_for_built_in_types = true:suggestion +csharp_style_var_when_type_is_apparent = true:suggestion +csharp_style_var_elsewhere = true:suggestion + +# Code style defaults +csharp_preserve_single_line_blocks = true +csharp_preserve_single_line_statements = true + +# Prefer method-like constructs to have a block body +csharp_style_expression_bodied_methods = false:none +csharp_style_expression_bodied_constructors = false:none +csharp_style_expression_bodied_operators = false:none + +# Prefer property-like constructs to have an expression-body +csharp_style_expression_bodied_properties = true:none +csharp_style_expression_bodied_indexers = true:none +csharp_style_expression_bodied_accessors = true:none + +# Expression +csharp_prefer_simple_default_expression = true:suggestion +csharp_style_deconstructed_variable_declaration = true:suggestion +csharp_style_pattern_local_over_anonymous_function = true:suggestion + +# Pattern matching +csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion +csharp_style_pattern_matching_over_as_with_null_check = true:suggestion +csharp_style_inlined_variable_declaration = true:suggestion + +# Null checking preferences +csharp_style_throw_expression = true:suggestion +csharp_style_conditional_delegate_call = true:suggestion + +# Newline settings +csharp_new_line_before_open_brace = all +csharp_new_line_before_else = true +csharp_new_line_before_catch = true +csharp_new_line_before_finally = true +csharp_new_line_before_members_in_object_initializers = true +csharp_new_line_before_members_in_anonymous_types = true +csharp_new_line_between_query_expression_clauses = 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 = do_not_ignore +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 = false +csharp_space_between_square_brackets = false diff --git a/SourceGeneratorExample/Directory.Build.props b/SourceGeneratorExample/Directory.Build.props new file mode 100644 index 0000000..f5a0089 --- /dev/null +++ b/SourceGeneratorExample/Directory.Build.props @@ -0,0 +1,10 @@ + + + + $(MSBuildThisFileDirectory)key.snk + latest + true + embedded + + + diff --git a/SourceGeneratorExample/SourceGeneratorExample.Roslyn38/SourceGeneratorExample.Roslyn38.csproj b/SourceGeneratorExample/SourceGeneratorExample.Roslyn38/SourceGeneratorExample.Roslyn38.csproj new file mode 100644 index 0000000..c03c7f2 --- /dev/null +++ b/SourceGeneratorExample/SourceGeneratorExample.Roslyn38/SourceGeneratorExample.Roslyn38.csproj @@ -0,0 +1,20 @@ + + + + netstandard2.0 + SourceGeneratorExampleV1 + SourceGeneratorExample + false + true + enable + + + + + + + + + + + diff --git a/SourceGeneratorExample/SourceGeneratorExample.Roslyn40/SourceGeneratorExample.Roslyn40.csproj b/SourceGeneratorExample/SourceGeneratorExample.Roslyn40/SourceGeneratorExample.Roslyn40.csproj new file mode 100644 index 0000000..f03f7f8 --- /dev/null +++ b/SourceGeneratorExample/SourceGeneratorExample.Roslyn40/SourceGeneratorExample.Roslyn40.csproj @@ -0,0 +1,21 @@ + + + + netstandard2.0 + SourceGeneratorExampleV2 + SourceGeneratorExample + false + true + enable + $(DefineConstants);ROSLYN_4 + + + + + + + + + + + diff --git a/SourceGeneratorExample/SourceGeneratorExample.Shared/SourceGeneratorExample.cs b/SourceGeneratorExample/SourceGeneratorExample.Shared/SourceGeneratorExample.cs new file mode 100644 index 0000000..9b6457f --- /dev/null +++ b/SourceGeneratorExample/SourceGeneratorExample.Shared/SourceGeneratorExample.cs @@ -0,0 +1,123 @@ +using System; +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 Microsoft.CodeAnalysis.Text; + +// File-scoped namespace +namespace SourceGeneratorExample; + +[Generator] +#if ROSLYN_4 +public class InterfaceStubGeneratorV2 : IIncrementalGenerator +#else +public class InterfaceStubGenerator : ISourceGenerator +#endif +{ + +#if !ROSLYN_4 + + public void Execute(GeneratorExecutionContext context) + { + if (context.SyntaxReceiver is not SyntaxReceiver receiver) + return; + + context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.ThisPropertysValueCanBeUsedInTheGenerator", out var someBuildTimeProperty); + + GeneratorCodeWithContext( + context, + static (context, diagnostic) => context.ReportDiagnostic(diagnostic), + static (context, hintName, sourceText) => context.AddSource(hintName, sourceText), + (CSharpCompilation)context.Compilation, + someBuildTimeProperty, + receiver.CandidateProperties.ToImmutableArray()); + } + +#endif + + public void GeneratorCodeWithContext( + TContext context, + Action reportDiagnostic, + Action addSource, + CSharpCompilation compilation, + string? someBuildTimeProperty, + ImmutableArray candidateProperties) + { + // Do something to generate code and call addSource with the contents + + } + + + +#if ROSLYN_4 + + public void Initialize(IncrementalGeneratorInitializationContext context) + { + // See docs ____ for more details on incremental generators + + // Here we're looking for Properties with an attribute that are in a class + var candidatePropertiesProvider = context.SyntaxProvider.CreateSyntaxProvider( + (syntax, cancellationToken) => syntax is PropertyDeclarationSyntax { Parent: ClassDeclarationSyntax, AttributeLists: { Count: > 0 } }, + (context, cancellationToken) => (PropertyDeclarationSyntax)context.Node); + + var someBuildTimeProperty = context.AnalyzerConfigOptionsProvider.Select( + (analyzerConfigOptionsProvider, cancellationToken) => analyzerConfigOptionsProvider.GlobalOptions.TryGetValue("build_property.ThisPropertysValueCanBeUsedInTheGenerator", out var someBuildTimeProperty) ? someBuildTimeProperty : null); + + var inputs = candidatePropertiesProvider.Collect() + .Combine(someBuildTimeProperty) + .Select((combined, cancellationToken) => (candidateProperties: combined.Left, someBuildTimeProperty: combined.Right)) + .Combine(context.CompilationProvider) + .Select((combined, cancellationToken) => (combined.Left.candidateProperties, combined.Left.someBuildTimeProperty, compilation: combined.Right)); + + + + context.RegisterSourceOutput( + inputs, + (context, collectedValues) => + { + GeneratorCodeWithContext( + context, + static (context, diagnostic) => context.ReportDiagnostic(diagnostic), + static (context, hintName, sourceText) => context.AddSource(hintName, sourceText), + (CSharpCompilation)collectedValues.compilation, + collectedValues.someBuildTimeProperty, + collectedValues.candidateProperties); + }); + } + +#else + + public void Initialize(GeneratorInitializationContext context) + { + context.RegisterForSyntaxNotifications(() => new SyntaxReceiver()); + } + + class SyntaxReceiver : ISyntaxReceiver + { + // Example of something to store for later + public List CandidateProperties { get; } = new(); + + /// + /// Called for every syntax node in the compilation, we can inspect the nodes and save any information useful for generation + /// + public void OnVisitSyntaxNode(SyntaxNode syntaxNode) + { + // Look for things you need to use later in the generator, and store them + + // We're looking for properties with an attribute that are in a class + if (syntaxNode is PropertyDeclarationSyntax propertyDeclarationSyntax && + propertyDeclarationSyntax.Parent is ClassDeclarationSyntax && + propertyDeclarationSyntax.AttributeLists.Count > 0) + { + CandidateProperties.Add(propertyDeclarationSyntax); + } + } + } + +#endif +} diff --git a/SourceGeneratorExample/SourceGeneratorExample.sln b/SourceGeneratorExample/SourceGeneratorExample.sln new file mode 100644 index 0000000..b3a29b3 --- /dev/null +++ b/SourceGeneratorExample/SourceGeneratorExample.sln @@ -0,0 +1,85 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.1.31911.260 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{4F1C8991-7097-4471-A9A6-A72005AB594D}" + ProjectSection(SolutionItems) = preProject + .editorconfig = .editorconfig + Directory.build.props = Directory.build.props + EndProjectSection +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SourceGeneratorExample.Roslyn38", "SourceGeneratorExample.Roslyn38\SourceGeneratorExample.Roslyn38.csproj", "{72869789-0310-4916-9A41-20D16A01C1B8}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SourceGeneratorExample.Roslyn40", "SourceGeneratorExample.Roslyn40\SourceGeneratorExample.Roslyn40.csproj", "{A4B61169-3314-41DB-8156-BE9677C90C9F}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SourceGeneratorExample", "SourceGeneratorExample\SourceGeneratorExample.csproj", "{91F99B24-FD91-46AA-95BC-CC874EEF95EA}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|ARM = Debug|ARM + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|Any CPU = Release|Any CPU + Release|ARM = Release|ARM + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {72869789-0310-4916-9A41-20D16A01C1B8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {72869789-0310-4916-9A41-20D16A01C1B8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {72869789-0310-4916-9A41-20D16A01C1B8}.Debug|ARM.ActiveCfg = Debug|Any CPU + {72869789-0310-4916-9A41-20D16A01C1B8}.Debug|ARM.Build.0 = Debug|Any CPU + {72869789-0310-4916-9A41-20D16A01C1B8}.Debug|x64.ActiveCfg = Debug|Any CPU + {72869789-0310-4916-9A41-20D16A01C1B8}.Debug|x64.Build.0 = Debug|Any CPU + {72869789-0310-4916-9A41-20D16A01C1B8}.Debug|x86.ActiveCfg = Debug|Any CPU + {72869789-0310-4916-9A41-20D16A01C1B8}.Debug|x86.Build.0 = Debug|Any CPU + {72869789-0310-4916-9A41-20D16A01C1B8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {72869789-0310-4916-9A41-20D16A01C1B8}.Release|Any CPU.Build.0 = Release|Any CPU + {72869789-0310-4916-9A41-20D16A01C1B8}.Release|ARM.ActiveCfg = Release|Any CPU + {72869789-0310-4916-9A41-20D16A01C1B8}.Release|ARM.Build.0 = Release|Any CPU + {72869789-0310-4916-9A41-20D16A01C1B8}.Release|x64.ActiveCfg = Release|Any CPU + {72869789-0310-4916-9A41-20D16A01C1B8}.Release|x64.Build.0 = Release|Any CPU + {72869789-0310-4916-9A41-20D16A01C1B8}.Release|x86.ActiveCfg = Release|Any CPU + {72869789-0310-4916-9A41-20D16A01C1B8}.Release|x86.Build.0 = Release|Any CPU + {A4B61169-3314-41DB-8156-BE9677C90C9F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A4B61169-3314-41DB-8156-BE9677C90C9F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A4B61169-3314-41DB-8156-BE9677C90C9F}.Debug|ARM.ActiveCfg = Debug|Any CPU + {A4B61169-3314-41DB-8156-BE9677C90C9F}.Debug|ARM.Build.0 = Debug|Any CPU + {A4B61169-3314-41DB-8156-BE9677C90C9F}.Debug|x64.ActiveCfg = Debug|Any CPU + {A4B61169-3314-41DB-8156-BE9677C90C9F}.Debug|x64.Build.0 = Debug|Any CPU + {A4B61169-3314-41DB-8156-BE9677C90C9F}.Debug|x86.ActiveCfg = Debug|Any CPU + {A4B61169-3314-41DB-8156-BE9677C90C9F}.Debug|x86.Build.0 = Debug|Any CPU + {A4B61169-3314-41DB-8156-BE9677C90C9F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A4B61169-3314-41DB-8156-BE9677C90C9F}.Release|Any CPU.Build.0 = Release|Any CPU + {A4B61169-3314-41DB-8156-BE9677C90C9F}.Release|ARM.ActiveCfg = Release|Any CPU + {A4B61169-3314-41DB-8156-BE9677C90C9F}.Release|ARM.Build.0 = Release|Any CPU + {A4B61169-3314-41DB-8156-BE9677C90C9F}.Release|x64.ActiveCfg = Release|Any CPU + {A4B61169-3314-41DB-8156-BE9677C90C9F}.Release|x64.Build.0 = Release|Any CPU + {A4B61169-3314-41DB-8156-BE9677C90C9F}.Release|x86.ActiveCfg = Release|Any CPU + {A4B61169-3314-41DB-8156-BE9677C90C9F}.Release|x86.Build.0 = Release|Any CPU + {91F99B24-FD91-46AA-95BC-CC874EEF95EA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {91F99B24-FD91-46AA-95BC-CC874EEF95EA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {91F99B24-FD91-46AA-95BC-CC874EEF95EA}.Debug|ARM.ActiveCfg = Debug|Any CPU + {91F99B24-FD91-46AA-95BC-CC874EEF95EA}.Debug|ARM.Build.0 = Debug|Any CPU + {91F99B24-FD91-46AA-95BC-CC874EEF95EA}.Debug|x64.ActiveCfg = Debug|Any CPU + {91F99B24-FD91-46AA-95BC-CC874EEF95EA}.Debug|x64.Build.0 = Debug|Any CPU + {91F99B24-FD91-46AA-95BC-CC874EEF95EA}.Debug|x86.ActiveCfg = Debug|Any CPU + {91F99B24-FD91-46AA-95BC-CC874EEF95EA}.Debug|x86.Build.0 = Debug|Any CPU + {91F99B24-FD91-46AA-95BC-CC874EEF95EA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {91F99B24-FD91-46AA-95BC-CC874EEF95EA}.Release|Any CPU.Build.0 = Release|Any CPU + {91F99B24-FD91-46AA-95BC-CC874EEF95EA}.Release|ARM.ActiveCfg = Release|Any CPU + {91F99B24-FD91-46AA-95BC-CC874EEF95EA}.Release|ARM.Build.0 = Release|Any CPU + {91F99B24-FD91-46AA-95BC-CC874EEF95EA}.Release|x64.ActiveCfg = Release|Any CPU + {91F99B24-FD91-46AA-95BC-CC874EEF95EA}.Release|x64.Build.0 = Release|Any CPU + {91F99B24-FD91-46AA-95BC-CC874EEF95EA}.Release|x86.ActiveCfg = Release|Any CPU + {91F99B24-FD91-46AA-95BC-CC874EEF95EA}.Release|x86.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {6E9C2873-AFF9-4D32-A784-1BA094814054} + EndGlobalSection +EndGlobal diff --git a/SourceGeneratorExample/SourceGeneratorExample/SourceGeneratorExample.csproj b/SourceGeneratorExample/SourceGeneratorExample/SourceGeneratorExample.csproj new file mode 100644 index 0000000..9f649c0 --- /dev/null +++ b/SourceGeneratorExample/SourceGeneratorExample/SourceGeneratorExample.csproj @@ -0,0 +1,33 @@ + + + + netstandard2.0 + false + MIT + + + + + + + + + + + + + + + + + + + + + diff --git a/SourceGeneratorExample/SourceGeneratorExample/targets/SourceGeneratorExample.props b/SourceGeneratorExample/SourceGeneratorExample/targets/SourceGeneratorExample.props new file mode 100644 index 0000000..24a64ce --- /dev/null +++ b/SourceGeneratorExample/SourceGeneratorExample/targets/SourceGeneratorExample.props @@ -0,0 +1,7 @@ + + + + + + + diff --git a/SourceGeneratorExample/SourceGeneratorExample/targets/SourceGeneratorExample.targets b/SourceGeneratorExample/SourceGeneratorExample/targets/SourceGeneratorExample.targets new file mode 100644 index 0000000..6000ff8 --- /dev/null +++ b/SourceGeneratorExample/SourceGeneratorExample/targets/SourceGeneratorExample.targets @@ -0,0 +1,57 @@ + + + + + + $(RootNamespace) + + + <_SourceGeneratorExampleMSBuildMinVersion>16.8.0 + + + + + + <_SourceGeneratorExampleAnalyzer Include="@(Analyzer)" Condition="'%(Analyzer.NuGetPackageId)' == 'SourceGeneratorExample'" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/SourceGeneratorExample/key.snk b/SourceGeneratorExample/key.snk new file mode 100644 index 0000000000000000000000000000000000000000..f62f66301a2cdc83d82df3e5937104656dfc57b6 GIT binary patch literal 596 zcmV-a0;~N80ssI2Bme+XQ$aES1ONa500988S~=xo;Fi*f#`smsw<1JxDr)>b<7qK1 zfA&ZaR*(gP{ab1XrnD^BV;HhREcK$%xDjF4ilq4D$OaZKIp<`pci-lJF+jav zx23BE4?jD;MNrF-@{$|maFxr9g}!-NdyiH!ca7d?o?FgvdIdxNJHY*Mnc@X{zz2V# znw)uetnDZm5ns#icX|ew0rcbXh`5upd>Ik5^1wjFsSMe#ZcbNr~fT+<8^&dCJ|fR>9q!a zyv68k4?Tm>V%5P-A_JpEqe%jRP$;2%3hFeCRJ`G_wT8 Date: Tue, 30 Nov 2021 11:04:48 -0500 Subject: [PATCH 2/2] Update readme --- README.md | 2 ++ .../SourceGeneratorExample.Shared/SourceGeneratorExample.cs | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index fdfb270..56ec62b 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,8 @@ This project has adopted the [Microsoft Open Source Code of Conduct](https://ope 1. [PackageSourceMappingExample](PackageSourceMappingExample) is a sample solution that shows how to configure Package Source Mapping for a couple projects and packages. [The README](PackageSourceMappingExample/README.md) contains many smaller example scenarios and results. +1. [SourceGeneratorSample](SourceGeneratorSample) is a sample solution showing how to build and pack a Source Generator that targets multiple Roslyn API versions. For more information see [Source Generators](https://docs.microsoft.com/en-us/dotnet/csharp/roslyn-sdk/source-generators-overview) + ## Documentation and Further Learning The [NuGet Docs](http://docs.nuget.org) cover creating NuGet packages in more detail: diff --git a/SourceGeneratorExample/SourceGeneratorExample.Shared/SourceGeneratorExample.cs b/SourceGeneratorExample/SourceGeneratorExample.Shared/SourceGeneratorExample.cs index 9b6457f..94b0cad 100644 --- a/SourceGeneratorExample/SourceGeneratorExample.Shared/SourceGeneratorExample.cs +++ b/SourceGeneratorExample/SourceGeneratorExample.Shared/SourceGeneratorExample.cs @@ -52,13 +52,13 @@ public void GeneratorCodeWithContext( } - + #if ROSLYN_4 public void Initialize(IncrementalGeneratorInitializationContext context) { - // See docs ____ for more details on incremental generators + // See docs https://docs.microsoft.com/en-us/dotnet/csharp/roslyn-sdk/source-generators-overview for more details on incremental generators // Here we're looking for Properties with an attribute that are in a class var candidatePropertiesProvider = context.SyntaxProvider.CreateSyntaxProvider(