diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index ca9f810..ae826a8 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -35,28 +35,36 @@ jobs:
with:
dotnet-version: '9.0.x'
+ - name: Get tag for current commit
+ id: get_tag
+ # Check for tags when triggered by main branch push (with tag) or direct tag push
+ # Can't use github.ref_name because it's "main" when pushing branch+tag together
+ if: github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/')
+ uses: olegtarasov/get-tag@v2.1.4
+
+ - name: Set Version Profile
+ run: |
+ if [[ "${{ steps.get_tag.outputs.tag }}" != "" ]]; then
+ echo "VERSION_PROFILE=release" >> $GITHUB_ENV
+ else
+ echo "VERSION_PROFILE=ci" >> $GITHUB_ENV
+ fi
+
- name: Restore dependencies
run: dotnet restore $SOLUTION
- name: Build
- run: dotnet build $SOLUTION --configuration $BUILD_CONFIG --no-restore
+ run: dotnet build $SOLUTION --configuration $BUILD_CONFIG --no-restore -p:GeneratePackageOnBuild=false -p:VersionProfile=${{ env.VERSION_PROFILE }}
- name: Run tests
- run: dotnet test --configuration $BUILD_CONFIG --no-restore --no-build --verbosity normal
+ run: dotnet test --configuration $BUILD_CONFIG --no-restore --no-build --verbosity normal -p:VersionProfile=${{ env.VERSION_PROFILE }}
- name: Pack NuGet packages
run: |
- dotnet pack $SOLUTION --configuration $BUILD_CONFIG --no-build --output ./artifacts
+ dotnet pack $SOLUTION --configuration $BUILD_CONFIG --no-build --output ./artifacts -p:VersionProfile=${{ env.VERSION_PROFILE }}
echo "=== Packages created ==="
ls -la ./artifacts/
- - name: Get tag for current commit
- id: get_tag
- # Check for tags when triggered by main branch push (with tag) or direct tag push
- # Can't use github.ref_name because it's "main" when pushing branch+tag together
- if: github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/')
- uses: olegtarasov/get-tag@v2.1.4
-
- name: Extract release notes from CHANGELOG.md
if: steps.get_tag.outputs.tag != ''
id: extract_notes
diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml
index 352071f..bcbf610 100644
--- a/.github/workflows/publish.yml
+++ b/.github/workflows/publish.yml
@@ -21,8 +21,8 @@ jobs:
- name: Restore, Build, and Pack
run: |
dotnet restore *.sln
- dotnet build *.sln --configuration Release --no-restore -p:ContinuousIntegrationBuild=true
- dotnet pack *.sln --configuration Release --no-build --output ./artifacts -p:ContinuousIntegrationBuild=true
+ dotnet build *.sln --configuration Release --no-restore -p:ContinuousIntegrationBuild=true -p:GeneratePackageOnBuild=false -p:VersionProfile=release
+ dotnet pack *.sln --configuration Release --no-build --output ./artifacts -p:ContinuousIntegrationBuild=true -p:VersionProfile=release
- name: Publish to NuGet
run: dotnet nuget push ./artifacts/*.nupkg --api-key ${{ secrets.NUGET_API_KEY }} --source https://api.nuget.org/v3/index.json --skip-duplicate
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9d5d360..c36a412 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,11 +2,24 @@
All notable changes to this project will be documented in this file.
-The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
+The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
+## [1.0.0] - 2025-08-03
+
+### Changed
+
+- Massive simplification by using Datacute.IncrementalGeneratorExtensions
+- Changed to use a builder style pattern for the pipeline Combines.
+- Replaced Numerous Attribute "Include x" Properties with a single flags enum.
+- Generate flags enum and attribute rather than including them in the package. (This results in more consistent package treatment as a source generator.)
+
+### Added
+
+- More docs
+
## [0.0.2-alpha] - 2025-07-12
### Fixed
@@ -58,5 +71,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- MetadataReferencesProvider's MetadataReference details
- Diagnostic log of the source generation process and timing included.
-[Unreleased]: https://github.com/datacute/SourceGeneratorContext/compare/0.0.1-alpha...develop
-[0.0.1-alpha]: https://github.com/datacute/SourceGeneratorContext/releases/0.0.1-alpha
\ No newline at end of file
+[Unreleased]: https://github.com/datacute/SourceGeneratorContext/compare/1.0.0...develop
+[1.0.0]: https://github.com/datacute/SourceGeneratorContext/releases/tag/1.0.0
+[0.0.2-alpha]: https://github.com/datacute/SourceGeneratorContext/releases/tag/0.0.2-alpha
+[0.0.1-alpha]: https://github.com/datacute/SourceGeneratorContext/releases/tag/0.0.1-alpha
diff --git a/README.md b/README.md
index e7a622e..3896051 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,331 @@
-# SourceGeneratorContext
-A source generator to help creators of source generators, by creating doc-comments showing the available generation context.
+# Datacute Source Generator Context
+A source generator to help creators of source generators learn what information is available,
+by creating doc-comments showing the available generation context.
+
+# Audience
+
+This source generator is intended for developers creating source generators,
+who want to understand the context available to them during the generation process.
+
+# Installation
+
+Add the NuGet package `Datacute.SourceGeneratorContext`
+
+The package includes both the source generator and a marker attribute dll.
+The marker attribute is used to indicate whereabouts in your project that the
+source generator context should be generated.
+
+The marker attribute does not need to be included in your project's output assembly,
+so the package reference in you `.csproj` file can be marked as `PrivateAssets="all" ExcludeAssets="runtime"` as follows:
+
+```xml
+
+
+
+```
+
+# Usage
+
+To use the source generator, create a partial class in your project and decorate it with the `[SourceGeneratorContext]` attribute.
+
+```csharp
+using Datacute.SourceGeneratorContext;
+
+[SourceGeneratorContext]
+public partial class MySourceGeneratorContext
+{
+ // This class will be populated with doc-comments showing the available context for source generation.
+}
+```
+
+# Attribute Flags
+
+The `SourceGeneratorContext` attribute can be configured with flags to control which parts of the context are included in the generated output.
+
+If any value is null or empty, the row is not included in the generated output.
+
+### No flags or `IncludeFlags.Summary` (default)
+If no other specific flags are set, `IncludeFlags.AttributeContextTargetSymbol` is used.
+
+(This will change in a future version to be a small selection of various properties.)
+
+### `IncludeFlags.AttributeContextTargetSymbol`
+Includes details about the GeneratorAttributeSyntaxContext.TargetSymbol. This is the default information provided if no flags are specified (see `Summary`).
+
+| Property | Value |
+|---------------------------------------|---------------------------------------------------------------|
+| Type | The runtime Type of this symbol |
+| Kind | The kind of this symbol |
+| Language | The language (C# or VB) that this symbol was declared in |
+| DeclaredAccessibility | The declared accessibility of the symbol |
+| ContainingSymbol Kind | The kind of the containing symbol |
+| ContainingSymbol Name | The name of the containing symbol |
+| ContainingAssembly Name | The name of the containing assembly |
+| ContainingModule Name | The name of the containing module |
+| ContainingType Name | The name of the containing type |
+| ContainingType Generic Types | The number of generic type parameters for the containing type |
+| ContainingType Generic Type n | The display string of the generic type parameter |
+| ContainingNamespace Name | The name of the containing namespace |
+| ContainingNamespace IsGlobalNamespace | True if the containing namespace is the global namespace |
+| Name | The name of the symbol |
+| MetadataName | The name of the symbol as it appears in metadata |
+| MetadataToken | The metadata token of the symbol |
+| IsDefinition | True if this symbol is a definition |
+| IsStatic | True if this symbol is static |
+| IsVirtual | True if this symbol is virtual |
+| IsOverride | True if this symbol is an override |
+| IsAbstract | True if this symbol is abstract (or an interface) |
+| IsSealed | True if this symbol is sealed (or a struct) |
+| IsExtern | True if this symbol is extern |
+| IsImplicitlyDeclared | True if this symbol was implicitly declared |
+| CanBeReferencedByName | True if this symbol can be referenced by name |
+
+### `IncludeFlags.AttributeContextTypeSymbol`
+Includes details about the GeneratorAttributeSyntaxContext.TargetSymbol when cast to an ITypeSymbol.
+
+| Property | Value |
+|----------------------|-------------------------------------------------|
+| TypeKind | The kind of the type |
+| BaseType Name | The name of the base type |
+| Interfaces Length | The number of directly implemented interfaces |
+| Interface n | The display string of the implemented interface |
+| AllInterfaces Length | The number of all implemented interfaces |
+| AllInterfaces n | The display string of the implemented interface |
+| IsReferenceType | True if the type is a reference type |
+| IsValueType | True if the type is a value type |
+| IsAnonymousType | True if the type is an anonymous type |
+| IsTupleType | True if the type is a tuple type |
+| IsNativeIntegerType | True if the type is a native integer type |
+| SpecialType | The special type of the type |
+| IsRefLikeType | True if the type is a ref-like type |
+| IsUnmanagedType | True if the type is an unmanaged type |
+| IsReadOnly | True if the type is read-only |
+| IsRecord | True if the type is a record |
+| NullableAnnotation | The nullable annotation of the type |
+
+### `IncludeFlags.AttributeContextNamedTypeSymbol`
+Includes details about the GeneratorAttributeSyntaxContext.TargetSymbol when cast to an INamedTypeSymbol.
+
+| Property | Value |
+|------------------------------|--------------------------------------------------|
+| Arity | The number of type parameters |
+| IsGenericType | True if the type is generic |
+| IsUnboundGenericType | True if the type is an unbound generic type |
+| IsScriptClass | True if the type is a script class |
+| IsImplicitClass | True if the type is an implicit class |
+| IsComImport | True if the type is a COM import |
+| IsFileLocal | True if the type is a file-local type |
+| MemberNames | The number of member names |
+| TypeParameters | The number of type parameters |
+| TypeParameter n | The name of the type parameter |
+| InstanceConstructors | The number of instance constructors |
+| StaticConstructors | The number of static constructors |
+| MightContainExtensionMethods | True if the type might contain extension methods |
+| IsSerializable | True if the type is serializable |
+
+### `IncludeFlags.AttributeContextTargetNode`
+Includes details about the GeneratorAttributeSyntaxContext.TargetNode.
+
+| Property | Value |
+|---------------------|---------------------------------------------------|
+| Type | The runtime Type of this node |
+| RawKind | The raw kind of the node |
+| Kind | The kind of the node |
+| Language | The language of the node |
+| Span.Start | The start position of the node in the source text |
+| Span.Length | The length of the node in the source text |
+| ContainsAnnotations | True if the node contains annotations |
+| ContainsDiagnostics | True if the node contains diagnostics |
+| ContainsDirectives | True if the node contains directives |
+| ContainsSkippedText | True if the node contains skipped text |
+| IsMissing | True if the node is missing |
+| HasLeadingTrivia | True if the node has leading trivia |
+| HasStructuredTrivia | True if the node has structured trivia |
+| HasTrailingTrivia | True if the node has trailing trivia |
+| IsStructuredTrivia | True if the node is structured trivia |
+
+### `IncludeFlags.AttributeContextAttributes`
+Includes details about the GeneratorAttributeSyntaxContext.Attributes.
+
+| Property | Value |
+|--------------------------------------------|-------------------------------------------|
+| Attribute Count | The number of attributes |
+| [n] AttributeClass | The display string of the attribute class |
+| [n] ConstructorArguments Count | The number of constructor arguments |
+| [n] AttributeConstructor Parameters x Name | The name of the constructor parameter |
+| [n] ConstructorArgument x Kind | The kind of the constructor argument |
+| [n] ConstructorArgument x Type | The name of the constructor argument type |
+| [n] ConstructorArgument x Value | The value of the constructor argument |
+| [n] NamedArguments Count | The number of named arguments |
+| [n] NamedArgument x Key | The name of the named argument |
+| [n] NamedArgument x Value Kind | The kind of the named argument value |
+| [n] NamedArgument x Value Type | The name of the named argument value type |
+| [n] NamedArgument x Value Value | The value of the named argument |
+
+### `IncludeFlags.AttributeContextAllAttributes`
+Includes details about all attributes applied to the target symbol (using GetAttributes()).
+
+| Property | Value |
+|--------------------------------------------|-------------------------------------------|
+| Attribute Count | The number of attributes |
+| [n] AttributeClass | The display string of the attribute class |
+| [n] ConstructorArguments Count | The number of constructor arguments |
+| [n] AttributeConstructor Parameters x Name | The name of the constructor parameter |
+| [n] ConstructorArgument x Kind | The kind of the constructor argument |
+| [n] ConstructorArgument x Type | The name of the constructor argument type |
+| [n] ConstructorArgument x Value | The value of the constructor argument |
+| [n] NamedArguments Count | The number of named arguments |
+| [n] NamedArgument x Key | The name of the named argument |
+| [n] NamedArgument x Value Kind | The kind of the named argument value |
+| [n] NamedArgument x Value Type | The name of the named argument value type |
+| [n] NamedArgument x Value Value | The value of the named argument |
+
+### `IncludeFlags.GlobalOptions`
+Includes details from the `AnalyzerConfigOptionsProvider`'s `GlobalOptions`. Each key-value pair in the options will be added to the generated output.
+
+### `IncludeFlags.Compilation`
+Includes general details about the Compilation.
+
+| Property | Value |
+|-----------------------|-------------------------------------------|
+| AssemblyName | The name of the assembly |
+| Language | The language of the compilation |
+| IsCaseSensitive | True if the compilation is case-sensitive |
+| DynamicType | The dynamic type |
+| GlobalNamespace | The global namespace |
+| ObjectType | The object type |
+| ScriptClass | The script class |
+| SourceModule | The source module |
+| ScriptCompilationInfo | The script compilation info |
+| SyntaxTrees Count | The number of syntax trees |
+
+### `IncludeFlags.CompilationOptions`
+Includes details about the Compilation's options.
+
+| Property | Value |
+|-----------------------------------|---------------------------------------------------|
+| Language | The language of the options |
+| OutputKind | The output kind of the compilation |
+| ModuleName | The name of the module |
+| MainTypeName | The name of the main type |
+| ScriptClassName | The name of the script class |
+| CryptoKeyContainer | The crypto key container |
+| CryptoKeyFile | The crypto key file |
+| CryptoPublicKey Length | The length of the crypto public key |
+| DelaySign | True if delay signing is enabled |
+| CheckOverflow | True if overflow checking is enabled |
+| Platform | The platform of the compilation |
+| GeneralDiagnosticOption | The general diagnostic option |
+| WarningLevel | The warning level |
+| ReportSuppressedDiagnostics | True if suppressed diagnostics should be reported |
+| OptimizationLevel | The optimization level |
+| ConcurrentBuild | True if concurrent build is enabled |
+| Deterministic | True if the build is deterministic |
+| MetadataImportOptions | The metadata import options |
+| PublicSign | True if public signing is enabled |
+| NullableContextOptions | The nullable context options |
+| SpecificDiagnosticOptions Count | The number of specific diagnostic options |
+| SpecificDiagnosticOptions '{key}' | The value of the specific diagnostic option |
+
+### `IncludeFlags.CompilationAssembly`
+Includes details about the Compilation's assembly.
+
+| Property | Value |
+|------------------------------|------------------------------------------------------|
+| Identity Name | The name of the assembly identity |
+| Identity Version | The version of the assembly identity |
+| Identity CultureName | The culture name of the assembly identity |
+| Identity Flags | The flags of the assembly identity |
+| Identity ContentType | The content type of the assembly identity |
+| Identity HasPublicKey | True if the assembly identity has a public key |
+| Identity PublicKey Length | The length of the public key |
+| Identity IsStrongName | True if the assembly identity has a strong name |
+| Identity IsRetargetable | True if the assembly identity is retargetable |
+| IsInteractive | True if the assembly is interactive |
+| Modules Count | The number of modules |
+| TypeNames Count | The number of type names |
+| NamespaceNames Count | The number of namespace names |
+| MightContainExtensionMethods | True if the assembly might contain extension methods |
+| Language | The language of the assembly |
+| Name | The name of the assembly |
+| MetadataName | The metadata name of the assembly |
+| MetadataToken | The metadata token of the assembly |
+| Locations Length | The number of locations |
+| DeclaredAccessibility | The declared accessibility of the assembly |
+
+### `IncludeFlags.CompilationReferences`
+Includes counts and names of Compilation's references (e.g., References, DirectiveReferences).
+
+| Property | Value |
+|-------------------------------|-----------------------------------------|
+| References Count | The number of references |
+| DirectiveReferences Count | The number of directive references |
+| ExternalReferences Count | The number of external references |
+| ReferencedAssemblyNames Count | The number of referenced assembly names |
+
+### `IncludeFlags.ParseOptions`
+Includes details about the ParseOptionsProvider's ParseOptions.
+
+| Property | Value |
+|---------------------------------|-----------------------------------------|
+| Kind | The kind of the parse options |
+| SpecifiedKind | The specified kind of the parse options |
+| DocumentationMode | The documentation mode |
+| Language | The language of the parse options |
+| CSharp SpecifiedLanguageVersion | The specified C# language version |
+| CSharp LanguageVersion | The C# language version |
+| Features Count | The number of features |
+| PreprocessorSymbolNames Count | The number of preprocessor symbol names |
+| PreprocessorSymbolName | A preprocessor symbol name |
+
+### `IncludeFlags.AdditionalTexts`
+Includes details about AdditionalTextsProvider's AdditionalText entries.
+
+| Property | Value |
+|-------------------|-------------------------------------------|
+| Path | The path to the additional text file |
+| Length | The length of the source text |
+| Encoding | The encoding of the source text |
+| Lines | The number of lines in the source text |
+| ChecksumAlgorithm | The checksum algorithm of the source text |
+| CanBeEmbedded | True if the source text can be embedded |
+
+### `IncludeFlags.AdditionalTextsOptions`
+Includes details about `AdditionalTextsProvider`'s `AdditionalText` options (from `AnalyzerConfigOptions`).
+For each additional text file, each key-value pair in the options will be added to the generated output.
+
+### `IncludeFlags.MetadataReferences`
+Includes details about `MetadataReferencesProvider`'s `MetadataReference` entries.
+A `MetadataReference` represents a reference to a metadata assembly, such as a .NET assembly.
+This allows a source generator to inspect the types and members defined in referenced assemblies,
+which can be useful for generating code that interacts with existing libraries.
+
+Due to the potentially large number of metadata references,
+the generated output is limited to the display string of each reference.
+
+| Property | Value |
+|-------------------------------|------------------------------------------|
+| Display | The display string of the metadata reference |
+
+### `IncludeFlags.All`
+Includes all available details about the source generation context, combining the output of all other flags.
+
+### Not all available properties are included
+
+While ths lists above are extensive, there are more properties and 'getter' methods available in the context objects,
+and not all the information is included in the generated output.
+
+Additionally, new versions of the Roslyn compiler may add new properties
+to the context, which this source generator will not show.
+
+---
+
+
+
+
+###### Datacute - Acute Information Revelation Tools
+
+
+
+
diff --git a/SourceGeneratorContext.Attribute/SourceGeneratorContext.Attribute.csproj b/SourceGeneratorContext.Attribute/SourceGeneratorContext.Attribute.csproj
deleted file mode 100644
index 3fe0366..0000000
--- a/SourceGeneratorContext.Attribute/SourceGeneratorContext.Attribute.csproj
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
- netstandard2.0
- 12
- Datacute.SourceGeneratorContext.Attribute
- Datacute.SourceGeneratorContext
- false
- enable
- 1.0.0
-
-
-
- true
-
-
-
diff --git a/SourceGeneratorContext.Attribute/SourceGeneratorContextAttribute.cs b/SourceGeneratorContext.Attribute/SourceGeneratorContextAttribute.cs
deleted file mode 100644
index a207bc5..0000000
--- a/SourceGeneratorContext.Attribute/SourceGeneratorContextAttribute.cs
+++ /dev/null
@@ -1,134 +0,0 @@
-using System;
-// ReSharper disable UnusedAutoPropertyAccessor.Global Properties getters are not used as the source generator reads the source code.
-// ReSharper disable UnusedParameter.Local Unused parameters are used to demonstrate behaviour.
-
-namespace Datacute.SourceGeneratorContext;
-
-///
-/// Add this attribute to a partial class to generate doc-comments detailing the source generation context.
-///
-[System.Diagnostics.Conditional("DATACUTE_SOURCEGENERATORCONTEXTATTRIBUTE_USAGES")]
-[AttributeUsage(
- validOn: AttributeTargets.Class |
- AttributeTargets.Interface |
- AttributeTargets.Struct, // Method and Property should be allowed too
- Inherited = true, // Inherited to show how SyntaxProvider.ForAttributeWithMetadataName doesn't support inheritance
- AllowMultiple = true)] // AllowMultiple to show the differences when multiple attributes are applied
-public class SourceGeneratorContextAttribute : Attribute
-{
- ///
- /// There is a huge amount of information available, but Visual Studio does not scroll doc-comments.
- /// So either IncludeAll and view the generated source, or set one of the named parameters to control what gets output:
- ///
- /// [SourceGeneratorContext(IncludeAll = true)]
- /// internal partial class Example;
- ///
- ///
- public SourceGeneratorContextAttribute()
- {
- }
-
- ///
- /// Set to true to include all available details.
- ///
- public bool IncludeAll { get; set; }
-
- ///
- /// Set to true to include the GeneratorAttributeSyntaxContext.TargetSymbol details.
- ///
- public bool IncludeAttributeContextTargetSymbol { get; set; }
-
- ///
- /// Set to true to include the GeneratorAttributeSyntaxContext.TargetSymbol as ITypeSymbol details.
- ///
- public bool IncludeAttributeContextTypeSymbol { get; set; }
-
- ///
- /// Set to true to include the GeneratorAttributeSyntaxContext.TargetSymbol as INamedTypeSymbol details.
- ///
- public bool IncludeAttributeContextNamedTypeSymbol { get; set; }
-
- ///
- /// Set to true to include the GeneratorAttributeSyntaxContext.TargetNode details.
- ///
- public bool IncludeAttributeContextTargetNode { get; set; }
-
- ///
- /// Set to true to include the GeneratorAttributeSyntaxContext.Attributes details.
- ///
- public bool IncludeAttributeContextAttributes { get; set; }
-
- ///
- /// Set to true to include the GeneratorAttributeSyntaxContext.GetAttributes() details.
- ///
- public bool IncludeAttributeContextAllAttributes { get; set; }
-
- ///
- /// Set to true to include the AnalyzerConfigOptionsProvider's GlobalOptions details.
- ///
- public bool IncludeGlobalOptions { get; set; }
-
- ///
- /// Set to true to include the CompilationProvider's Compilation details.
- ///
- public bool IncludeCompilation { get; set; }
-
- ///
- /// Set to true to include the CompilationProvider's Compilation.Options details.
- ///
- public bool IncludeCompilationOptions { get; set; }
-
- ///
- /// Set to true to include the CompilationProvider's Compilation.Assembly details.
- ///
- public bool IncludeCompilationAssembly { get; set; }
-
- ///
- /// Set to true to include the Counts of CompilationProvider's Compilation.References, Compilation.DirectiveReferences, Compilation.ExternalReferences, and Compilation.ReferencedAssemblyNames.
- ///
- public bool IncludeCompilationReferences { get; set; }
-
- ///
- /// Set to true to include the ParseOptionsProvider's ParseOptions details.
- ///
- public bool IncludeParseOptions { get; set; }
-
- ///
- /// Set to true to include the AdditionalTextsProvider's AdditionalText details.
- ///
- public bool IncludeAdditionalTexts { get; set; }
-
- ///
- /// Set to true to include the AdditionalTextsProvider's AdditionalText details combined with AnalyzerConfigOptionsProvider's AnalyzerConfigOptions for the AdditionalText.
- ///
- public bool IncludeAdditionalTextsOptions { get; set; }
-
- ///
- /// Set to true to include the MetadataReferencesProvider's MetadataReference details.
- ///
- public bool IncludeMetadataReferences { get; set; }
-
-
- #region Demonstration purposes only
-
- ///
- /// Example of a named parameter.
- ///
- public string ExampleNamedParameter { get; set; } =
- string.Empty; // only used for demonstrating working with Named Parameters
-
- ///
- /// Example of an optional parameter.
- ///
- ///
- public
- SourceGeneratorContextAttribute(
- string? exampleOptionalParameter =
- null) // only used for demonstrating working with Constructor Arguments
- {
- // The constructor arguments do not need to be assigned to fields or properties
- // as the source of the supplied values is what is available to the source generator
- }
-
- #endregion
-}
\ No newline at end of file
diff --git a/SourceGeneratorContext.sln b/SourceGeneratorContext.sln
index 2f93387..caea35f 100644
--- a/SourceGeneratorContext.sln
+++ b/SourceGeneratorContext.sln
@@ -5,8 +5,6 @@ VisualStudioVersion = 17.13.35825.156 d17.13
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SourceGeneratorContext", "SourceGeneratorContext\SourceGeneratorContext.csproj", "{DB6CCC3F-D197-48F7-B166-E9194233939D}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SourceGeneratorContext.Attribute", "SourceGeneratorContext.Attribute\SourceGeneratorContext.Attribute.csproj", "{394AEA19-BF98-4427-BE95-BBD90A7D65A5}"
-EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SourceGeneratorContextExample", "SourceGeneratorContextExample\SourceGeneratorContextExample.csproj", "{56E79762-6BB4-4042-9EAB-2D819C2FDAB0}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{8EC462FD-D22E-90A8-E5CE-7E832BA40C5D}"
@@ -15,6 +13,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
Directory.Build.props = Directory.Build.props
LICENSE = LICENSE
version.props = version.props
+ global.json = global.json
+ versionsuffix.ci.props = versionsuffix.ci.props
+ versionsuffix.local.props = versionsuffix.local.props
+ versionsuffix.release.props = versionsuffix.release.props
EndProjectSection
EndProject
Global
@@ -27,10 +29,6 @@ Global
{DB6CCC3F-D197-48F7-B166-E9194233939D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DB6CCC3F-D197-48F7-B166-E9194233939D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DB6CCC3F-D197-48F7-B166-E9194233939D}.Release|Any CPU.Build.0 = Release|Any CPU
- {394AEA19-BF98-4427-BE95-BBD90A7D65A5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {394AEA19-BF98-4427-BE95-BBD90A7D65A5}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {394AEA19-BF98-4427-BE95-BBD90A7D65A5}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {394AEA19-BF98-4427-BE95-BBD90A7D65A5}.Release|Any CPU.Build.0 = Release|Any CPU
{56E79762-6BB4-4042-9EAB-2D819C2FDAB0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{56E79762-6BB4-4042-9EAB-2D819C2FDAB0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{56E79762-6BB4-4042-9EAB-2D819C2FDAB0}.Release|Any CPU.ActiveCfg = Release|Any CPU
diff --git a/SourceGeneratorContext/AdditionalTextDescription.cs b/SourceGeneratorContext/AdditionalTextDescription.cs
index 974fa5d..4091bbb 100644
--- a/SourceGeneratorContext/AdditionalTextDescription.cs
+++ b/SourceGeneratorContext/AdditionalTextDescription.cs
@@ -4,12 +4,12 @@
namespace Datacute.SourceGeneratorContext;
-public readonly struct AdditionalTextDescription
+public readonly record struct AdditionalTextDescription
{
public readonly string DocComments;
public readonly string OptionsComments;
- public AdditionalTextDescription(AdditionalText additionalText, AnalyzerConfigOptions? options = null)
+ private AdditionalTextDescription(AdditionalText additionalText, AnalyzerConfigOptions? options = null)
{
var sb = new StringBuilder();
sb.AddComment("Path", additionalText.Path);
@@ -36,16 +36,14 @@ public AdditionalTextDescription(AdditionalText additionalText, AnalyzerConfigOp
OptionsComments = sb.ToString();
}
- public static AdditionalTextDescription Select(AdditionalText additionalText, CancellationToken token)
+ public static AdditionalTextDescription Selector(AdditionalText additionalText, CancellationToken token)
{
token.ThrowIfCancellationRequested();
return new AdditionalTextDescription(additionalText);
}
- public static AdditionalTextDescription Select((AdditionalText additionalText, AnalyzerConfigOptionsProvider optionsProvider) args, CancellationToken token)
+ public static AdditionalTextDescription Selector((AdditionalText additionalText, AnalyzerConfigOptionsProvider optionsProvider) args, CancellationToken token)
{
- LightweightTrace.Add(TrackingNames.AdditionalTextDescription_Select);
-
token.ThrowIfCancellationRequested();
var options = args.optionsProvider.GetOptions(args.additionalText);
return new AdditionalTextDescription(args.additionalText, options);
diff --git a/SourceGeneratorContext/AnalyzerConfigOptionsDescription.cs b/SourceGeneratorContext/AnalyzerConfigOptionsDescription.cs
index f6087df..021cdcf 100644
--- a/SourceGeneratorContext/AnalyzerConfigOptionsDescription.cs
+++ b/SourceGeneratorContext/AnalyzerConfigOptionsDescription.cs
@@ -18,10 +18,8 @@ public AnalyzerConfigOptionsDescription(AnalyzerConfigOptions options)
DocComments = sb.ToString();
}
- public static AnalyzerConfigOptionsDescription Select(AnalyzerConfigOptionsProvider provider, CancellationToken token)
+ public static AnalyzerConfigOptionsDescription Selector(AnalyzerConfigOptionsProvider provider, CancellationToken token)
{
- LightweightTrace.Add(TrackingNames.AnalyzerConfigOptionsDescription_Select);
-
token.ThrowIfCancellationRequested();
return new AnalyzerConfigOptionsDescription(provider.GlobalOptions);
}
diff --git a/SourceGeneratorContext/AttributeContext.cs b/SourceGeneratorContext/AttributeContext.cs
deleted file mode 100644
index 0a354eb..0000000
--- a/SourceGeneratorContext/AttributeContext.cs
+++ /dev/null
@@ -1,427 +0,0 @@
-using System.Collections.Immutable;
-using System.Text;
-using Microsoft.CodeAnalysis;
-using Microsoft.CodeAnalysis.CSharp;
-
-namespace Datacute.SourceGeneratorContext;
-
-public readonly struct AttributeContext
-{
- // Store parent classes with their modifiers
- public record struct ParentClassInfo(
- string Name,
- bool IsStatic,
- Accessibility Accessibility,
- string RecordStructOrClass,
- string[] TypeParameters);
- public readonly ParentClassInfo[] ParentClasses { get; }
- public bool HasParentClasses => ParentClasses.Length > 0;
-
- public readonly bool IncludeSummary;
- public readonly bool IncludeAll;
-
- public readonly bool IncludeAttributeContextTargetSymbol;
- public readonly bool IncludeAttributeContextTypeSymbol;
- public readonly bool IncludeAttributeContextNamedTypeSymbol;
- public readonly bool IncludeAttributeContextTargetNode;
- public readonly bool IncludeAttributeContextAttributes;
- public readonly bool IncludeAttributeContextAllAttributes;
-
- public readonly bool IncludeGlobalOptions;
- public readonly bool IncludeCompilation;
- public readonly bool IncludeCompilationOptions;
- public readonly bool IncludeCompilationAssembly;
- public readonly bool IncludeCompilationReferences;
- public readonly bool IncludeParseOptions;
- public readonly bool IncludeAdditionalTexts;
- public readonly bool IncludeAdditionalTextsOptions;
- public readonly bool IncludeMetadataReferences;
-
- public readonly string TargetSymbolDocComments;
- public readonly string TypeSymbolDocComments;
- public readonly string NamedTypeSymbolDocComments;
- public readonly string TargetNodeDocComments;
- public readonly string AttributesDocComments;
- public readonly string AllAttributesDocComments;
-
- public readonly bool ContainingNamespaceIsGlobalNamespace;
- public readonly string ContainingNamespaceDisplayString;
-
- public readonly Accessibility DeclaredAccessibility; // public
- public readonly bool IsStatic; // static
- public readonly string RecordStructOrClass; // (partial) class
- public readonly string Name; // ClassName
- public readonly string[] TypeParameters; //
- public readonly string DisplayString; // Namespace.ClassName
-
- public AttributeContext(in GeneratorAttributeSyntaxContext generatorAttributeSyntaxContext)
- {
- var sb = new StringBuilder();
- var targetSymbol = generatorAttributeSyntaxContext.TargetSymbol;
- sb.AddComment("Type", targetSymbol.GetType().Name);
- sb.AddComment("Kind", targetSymbol.Kind);
- sb.AddComment("Language", targetSymbol.Language);
- sb.AddComment("DeclaredAccessibility", targetSymbol.DeclaredAccessibility);
- sb.AddComment("ContainingSymbol Kind", targetSymbol.ContainingSymbol?.Kind);
- sb.AddComment("ContainingSymbol Name", targetSymbol.ContainingSymbol?.Name);
- sb.AddComment("ContainingAssembly Name", targetSymbol.ContainingAssembly?.Name);
- sb.AddComment("ContainingModule Name", targetSymbol.ContainingModule?.Name);
- sb.AddComment("ContainingType Name", targetSymbol.ContainingType?.Name);
- var containingTypeTypeParameters = targetSymbol.ContainingType?.TypeParameters;
- sb.AddComment("ContainingType Generic Types", containingTypeTypeParameters?.Length);
- if (containingTypeTypeParameters != null)
- {
- for (var n = 0; n < containingTypeTypeParameters.Value.Length; n++)
- {
- var typeParameter = containingTypeTypeParameters.Value[n];
- sb.AddComment($"ContainingType Generic Type {n+1}", typeParameter.ToDisplayString());
- }
- }
- sb.AddComment("ContainingNamespace Name", targetSymbol.ContainingNamespace.Name);
- sb.AddComment("ContainingNamespace IsGlobalNamespace", targetSymbol.ContainingNamespace.IsGlobalNamespace);
- sb.AddComment("Name", targetSymbol.Name);
- sb.AddComment("MetadataName", targetSymbol.MetadataName);
- sb.AddComment("MetadataToken", targetSymbol.MetadataToken);
- sb.AddComment("IsDefinition", targetSymbol.IsDefinition);
- sb.AddComment("IsStatic", targetSymbol.IsStatic);
- sb.AddComment("IsVirtual", targetSymbol.IsVirtual);
- sb.AddComment("IsOverride", targetSymbol.IsOverride);
- sb.AddComment("IsAbstract", targetSymbol.IsAbstract);
- sb.AddComment("IsSealed", targetSymbol.IsSealed);
- sb.AddComment("IsExtern", targetSymbol.IsExtern);
- sb.AddComment("IsImplicitlyDeclared", targetSymbol.IsImplicitlyDeclared);
- sb.AddComment("CanBeReferencedByName", targetSymbol.CanBeReferencedByName);
-
- TargetSymbolDocComments = sb.ToString();
-
- sb.Clear();
-
- if (generatorAttributeSyntaxContext.TargetSymbol is ITypeSymbol typeTargetSymbol)
- {
- sb.AddComment("TypeKind", typeTargetSymbol.TypeKind);
- sb.AddComment("BaseType Name", typeTargetSymbol.BaseType?.Name ?? string.Empty);
- var interfaces = typeTargetSymbol.Interfaces;
- sb.AddComment("Interfaces Length", interfaces.Length);
- for (var n = 0; n < interfaces.Length; n++)
- {
- var directInterface = interfaces[n];
- sb.AddComment($"Interface {n+1}", directInterface.ToDisplayString());
- }
- var allInterfaces = typeTargetSymbol.AllInterfaces;
- sb.AddComment("AllInterfaces Length", allInterfaces.Length);
- for (var n = 0; n < allInterfaces.Length; n++)
- {
- var implementedInterface = allInterfaces[n];
- sb.AddComment($"Interface {n+1}", implementedInterface.ToDisplayString());
- }
- sb.AddComment("IsReferenceType", typeTargetSymbol.IsReferenceType);
- sb.AddComment("IsValueType", typeTargetSymbol.IsValueType);
- sb.AddComment("IsAnonymousType", typeTargetSymbol.IsAnonymousType);
- sb.AddComment("IsTupleType", typeTargetSymbol.IsTupleType);
- sb.AddComment("IsNativeIntegerType", typeTargetSymbol.IsNativeIntegerType);
- sb.AddComment("SpecialType", typeTargetSymbol.SpecialType);
- sb.AddComment("IsRefLikeType", typeTargetSymbol.IsRefLikeType);
- sb.AddComment("IsUnmanagedType", typeTargetSymbol.IsUnmanagedType);
- sb.AddComment("IsReadOnly", typeTargetSymbol.IsReadOnly);
- sb.AddComment("IsRecord", typeTargetSymbol.IsRecord);
- sb.AddComment("NullableAnnotation", typeTargetSymbol.NullableAnnotation);
-
- TypeSymbolDocComments = sb.ToString();
-
- sb.Clear();
- }
- else
- {
- TypeSymbolDocComments = string.Empty;
- }
-
- if (generatorAttributeSyntaxContext.TargetSymbol is INamedTypeSymbol namedTypeTargetSymbol)
- {
- TypeParameters = namedTypeTargetSymbol.TypeParameters.Select(tp => tp.Name).ToArray();
- sb.AddComment("Arity", namedTypeTargetSymbol.Arity);
- sb.AddComment("IsGenericType", namedTypeTargetSymbol.IsGenericType);
- sb.AddComment("IsUnboundGenericType", namedTypeTargetSymbol.IsUnboundGenericType);
- sb.AddComment("IsScriptClass", namedTypeTargetSymbol.IsScriptClass);
- sb.AddComment("IsImplicitClass", namedTypeTargetSymbol.IsImplicitClass);
- sb.AddComment("IsComImport", namedTypeTargetSymbol.IsComImport);
- sb.AddComment("IsFileLocal", namedTypeTargetSymbol.IsFileLocal);
- sb.AddComment("MemberNames", namedTypeTargetSymbol.MemberNames.Count());
- sb.AddComment("TypeParameters", TypeParameters.Length);
- for (var n = 0; n < TypeParameters.Length; n++)
- {
- var typeParameter = TypeParameters[n];
- sb.AddComment($"TypeParameter {n+1}", typeParameter);
- }
- sb.AddComment("InstanceConstructors", namedTypeTargetSymbol.InstanceConstructors.Length);
- sb.AddComment("StaticConstructors", namedTypeTargetSymbol.StaticConstructors.Length);
- sb.AddComment("MightContainExtensionMethods", namedTypeTargetSymbol.MightContainExtensionMethods);
- sb.AddComment("IsSerializable", namedTypeTargetSymbol.IsSerializable);
-
- NamedTypeSymbolDocComments = sb.ToString();
-
- sb.Clear();
- }
- else
- {
- TypeParameters = Array.Empty();
- NamedTypeSymbolDocComments = string.Empty;
- }
-
- var targetNode = generatorAttributeSyntaxContext.TargetNode;
- sb.AddComment("Type", targetNode.GetType().Name);
- sb.AddComment("RawKind", targetNode.RawKind);
- sb.AddComment("Kind", targetNode.Kind());
- sb.AddComment("Language", targetNode.Language);
- sb.AddComment("Span.Start", targetNode.Span.Start);
- sb.AddComment("Span.Length", targetNode.Span.Length);
- sb.AddComment("ContainsAnnotations", targetNode.ContainsAnnotations);
- sb.AddComment("ContainsDiagnostics", targetNode.ContainsDiagnostics);
- sb.AddComment("ContainsDirectives", targetNode.ContainsDirectives);
- sb.AddComment("ContainsSkippedText", targetNode.ContainsSkippedText);
- sb.AddComment("IsMissing", targetNode.IsMissing);
- sb.AddComment("HasLeadingTrivia", targetNode.HasLeadingTrivia);
- sb.AddComment("HasStructuredTrivia", targetNode.HasStructuredTrivia);
- sb.AddComment("HasTrailingTrivia", targetNode.HasTrailingTrivia);
- sb.AddComment("IsStructuredTrivia", targetNode.IsStructuredTrivia);
-
-
- TargetNodeDocComments = sb.ToString();
-
- sb.Clear();
-
- (
- IncludeSummary,
- IncludeAll,
- IncludeAttributeContextTargetSymbol,
- IncludeAttributeContextTypeSymbol,
- IncludeAttributeContextNamedTypeSymbol,
- IncludeAttributeContextTargetNode,
- IncludeAttributeContextAttributes,
- IncludeAttributeContextAllAttributes,
- IncludeGlobalOptions,
- IncludeCompilation,
- IncludeCompilationOptions,
- IncludeCompilationAssembly,
- IncludeCompilationReferences,
- IncludeParseOptions,
- IncludeAdditionalTexts,
- IncludeAdditionalTextsOptions,
- IncludeMetadataReferences) = AddAttributes(sb, generatorAttributeSyntaxContext.Attributes, true);
-
- AttributesDocComments = sb.ToString();
-
- sb.Clear();
-
- AddAttributes(sb, targetSymbol.GetAttributes(), false);
-
- AllAttributesDocComments = sb.ToString();
-
- sb.Clear();
-
- // Repeated above, but pulled out for ease of code generation
- var attributeTargetSymbol = (ITypeSymbol)generatorAttributeSyntaxContext.TargetSymbol;
-
- ContainingNamespaceIsGlobalNamespace = attributeTargetSymbol.ContainingNamespace.IsGlobalNamespace;
- ContainingNamespaceDisplayString = attributeTargetSymbol.ContainingNamespace.ToDisplayString();
-
- DeclaredAccessibility = attributeTargetSymbol.DeclaredAccessibility;
- IsStatic = attributeTargetSymbol.IsStatic;
- RecordStructOrClass = GetRecordStructOrClass(attributeTargetSymbol);
- Name = attributeTargetSymbol.Name;
- DisplayString = attributeTargetSymbol.ToDisplayString();
-
- // Parse parent classes from symbol's containing types
- var parentClasses = new List();
- var containingType = attributeTargetSymbol.ContainingType;
- while (containingType != null)
- {
- var typeParams = containingType.TypeParameters.Select(tp => tp.Name).ToArray();
-
- parentClasses.Insert(0, new ParentClassInfo(
- containingType.Name,
- containingType.IsStatic,
- containingType.DeclaredAccessibility,
- GetRecordStructOrClass(containingType),
- typeParams));
- containingType = containingType.ContainingType;
- }
-
- ParentClasses = parentClasses.ToArray();
- }
-
- private static (
- bool includeSummary,
- bool includeAll,
- bool includeAttributeContextTargetSymbol,
- bool includeAttributeContextTypeSymbol,
- bool includeAttributeContextNamedTypeSymbol,
- bool includeAttributeContextTargetNode,
- bool includeAttributeContextAttributes,
- bool includeAttributeContextAllAttributes,
- bool includeGlobalOptions,
- bool includeCompilation,
- bool includeCompilationOptions,
- bool includeCompilationAssembly,
- bool includeCompilationReferences,
- bool includeParseOptions,
- bool includeAdditionalTexts,
- bool includeAdditionalTextsOptions,
- bool includeMetadataReferences)
- AddAttributes(StringBuilder sb, ImmutableArray attributes, bool capture)
- {
- bool includeAll = false;
- bool includeSummary = true;
- bool includeAttributeContextTargetSymbol = false;
- bool includeAttributeContextTypeSymbol = false;
- bool includeAttributeContextNamedTypeSymbol = false;
- bool includeAttributeContextTargetNode = false;
- bool includeAttributeContextAttributes = false;
- bool includeAttributeContextAllAttributes = false;
- bool includeGlobalOptions = false;
- bool includeCompilation = false;
- bool includeCompilationOptions = false;
- bool includeCompilationAssembly = false;
- bool includeCompilationReferences = false;
- bool includeParseOptions = false;
- bool includeAdditionalTexts = false;
- bool includeAdditionalTextsOptions = false;
- bool includeMetadataReferences = false;
-
- sb.AddComment("Attribute Count", attributes.Length);
- for (var i = 0; i < attributes.Length; i++)
- {
- var attribute = attributes[i];
- sb.AddComment($"[{i}] AttributeClass", attribute.AttributeClass?.ToDisplayString());
-
- var constructorArguments = attribute.ConstructorArguments;
- var constructorArgumentsLength = constructorArguments.Length;
- sb.AddComment($"[{i}] ConstructorArguments Count", constructorArgumentsLength);
- for (var c = 0; c < constructorArgumentsLength; c++)
- {
- var constructorArgument = constructorArguments[c];
- var attributeName = attribute.AttributeConstructor?.Parameters[c].Name;
- sb.AddComment($"[{i}] AttributeConstructor Parameters {c+1} Name", attributeName);
- sb.AddComment($"[{i}] ConstructorArgument {c+1} Kind", constructorArgument.Kind);
- sb.AddComment($"[{i}] ConstructorArgument {c+1} Type", constructorArgument.Type?.Name);
- sb.AddComment($"[{i}] ConstructorArgument {c+1} Value", constructorArgument.Value);
-
- includeSummary = false;
- includeAttributeContextAttributes = true;
- }
-
- var namedArguments = attribute.NamedArguments;
- var namedArgumentsLength = namedArguments.Length;
- sb.AddComment($"[{i}] NamedArguments Count", namedArgumentsLength);
- for (var n = 0; n < namedArgumentsLength; n++)
- {
- var kvp = namedArguments[n];
- var argName = kvp.Key;
- var namedArgument = kvp.Value;
- sb.AddComment($"[{i}] NamedArgument {n+1} Key", argName);
- sb.AddComment($"[{i}] NamedArgument {n+1} Value Kind", namedArgument.Kind);
- sb.AddComment($"[{i}] NamedArgument {n+1} Value Type", namedArgument.Type?.Name);
- sb.AddComment($"[{i}] NamedArgument {n+1} Value Value", namedArgument.Value);
- if (capture)
- {
- includeSummary = false;
-
- var argumentValue = namedArgument.Value is true;
- switch (argName)
- {
- case "IncludeAll":
- includeAll = argumentValue;
- break;
- case "IncludeAttributeContextTargetSymbol":
- includeAttributeContextTargetSymbol |= argumentValue;
- break;
- case "IncludeAttributeContextTypeSymbol":
- includeAttributeContextTypeSymbol |= argumentValue;
- break;
- case "IncludeAttributeContextNamedTypeSymbol":
- includeAttributeContextNamedTypeSymbol |= argumentValue;
- break;
- case "IncludeAttributeContextTargetNode":
- includeAttributeContextTargetNode |= argumentValue;
- break;
- case "IncludeAttributeContextAttributes":
- includeAttributeContextAttributes |= argumentValue;
- break;
- case "IncludeAttributeContextAllAttributes":
- includeAttributeContextAllAttributes |= argumentValue;
- break;
- case "IncludeGlobalOptions":
- includeGlobalOptions |= argumentValue;
- break;
- case "IncludeCompilation":
- includeCompilation |= argumentValue;
- break;
- case "IncludeCompilationOptions":
- includeCompilationOptions |= argumentValue;
- break;
- case "IncludeCompilationAssembly":
- includeCompilationAssembly |= argumentValue;
- break;
- case "IncludeCompilationReferences":
- includeCompilationReferences |= argumentValue;
- break;
- case "IncludeParseOptions":
- includeParseOptions |= argumentValue;
- break;
- case "IncludeAdditionalTexts":
- includeAdditionalTexts |= argumentValue;
- break;
- case "IncludeAdditionalTextsOptions":
- includeAdditionalTextsOptions |= argumentValue;
- break;
- case "IncludeMetadataReferences":
- includeMetadataReferences |= argumentValue;
- break;
- default:
- includeAttributeContextAttributes = true;
- break;
- }
- }
- }
- }
-
- return (
- includeSummary,
- includeAll,
- includeAttributeContextTargetSymbol,
- includeAttributeContextTypeSymbol,
- includeAttributeContextNamedTypeSymbol,
- includeAttributeContextTargetNode,
- includeAttributeContextAttributes,
- includeAttributeContextAllAttributes,
- includeGlobalOptions,
- includeCompilation,
- includeCompilationOptions,
- includeCompilationAssembly,
- includeCompilationReferences,
- includeParseOptions,
- includeAdditionalTexts,
- includeAdditionalTextsOptions,
- includeMetadataReferences);
- }
-
- private static string GetRecordStructOrClass(ITypeSymbol typeSymbol)
- {
- if (typeSymbol.IsRecord && typeSymbol.IsReferenceType)
- return "record";
- if (typeSymbol.IsRecord)
- return "record struct";
- if (typeSymbol.TypeKind == TypeKind.Interface)
- return "interface";
- if (typeSymbol.IsReferenceType)
- return "class";
- return "struct";
- }
-
- public static bool Predicate(SyntaxNode syntaxNode, CancellationToken token) => true; //syntaxNode is TypeDeclarationSyntax,
-
- public static AttributeContext Transform(GeneratorAttributeSyntaxContext generatorAttributeSyntaxContext, CancellationToken token)
- {
- token.ThrowIfCancellationRequested();
- return new AttributeContext(generatorAttributeSyntaxContext);
- }
-}
\ No newline at end of file
diff --git a/SourceGeneratorContext/AttributeData.cs b/SourceGeneratorContext/AttributeData.cs
new file mode 100644
index 0000000..61568b8
--- /dev/null
+++ b/SourceGeneratorContext/AttributeData.cs
@@ -0,0 +1,247 @@
+using System.Collections.Immutable;
+using System.Text;
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CSharp;
+
+namespace Datacute.SourceGeneratorContext;
+
+public readonly record struct AttributeData
+{
+ public readonly IncludeFlags Flags;
+
+ public bool IncludeSummary => Flags == IncludeFlags.Summary;
+
+ public bool IncludeAttributeContextTargetSymbol => Flags.HasFlag(IncludeFlags.AttributeContextTargetSymbol);
+ public bool IncludeAttributeContextTypeSymbol => Flags.HasFlag(IncludeFlags.AttributeContextTypeSymbol);
+ public bool IncludeAttributeContextNamedTypeSymbol => Flags.HasFlag(IncludeFlags.AttributeContextNamedTypeSymbol);
+ public bool IncludeAttributeContextTargetNode => Flags.HasFlag(IncludeFlags.AttributeContextTargetNode);
+ public bool IncludeAttributeContextAttributes => Flags.HasFlag(IncludeFlags.AttributeContextAttributes);
+ public bool IncludeAttributeContextAllAttributes => Flags.HasFlag(IncludeFlags.AttributeContextAllAttributes);
+
+ public bool IncludeGlobalOptions => Flags.HasFlag(IncludeFlags.GlobalOptions);
+ public bool IncludeCompilation => Flags.HasFlag(IncludeFlags.Compilation);
+ public bool IncludeCompilationOptions => Flags.HasFlag(IncludeFlags.CompilationOptions);
+ public bool IncludeCompilationAssembly => Flags.HasFlag(IncludeFlags.CompilationAssembly);
+ public bool IncludeCompilationReferences => Flags.HasFlag(IncludeFlags.CompilationReferences);
+ public bool IncludeParseOptions => Flags.HasFlag(IncludeFlags.ParseOptions);
+ public bool IncludeAdditionalTexts => Flags.HasFlag(IncludeFlags.AdditionalTexts);
+ public bool IncludeAdditionalTextsOptions => Flags.HasFlag(IncludeFlags.AdditionalTextsOptions);
+ public bool IncludeMetadataReferences => Flags.HasFlag(IncludeFlags.MetadataReferences);
+
+ public readonly string TargetSymbolDocComments;
+ public readonly string TypeSymbolDocComments;
+ public readonly string NamedTypeSymbolDocComments;
+ public readonly string TargetNodeDocComments;
+ public readonly string AttributesDocComments;
+ public readonly string AllAttributesDocComments;
+
+
+ public AttributeData(in GeneratorAttributeSyntaxContext generatorAttributeSyntaxContext)
+ {
+ var sb = new StringBuilder();
+ var targetSymbol = generatorAttributeSyntaxContext.TargetSymbol;
+ sb.AddComment("Type", targetSymbol.GetType().Name);
+ sb.AddComment("Kind", targetSymbol.Kind);
+ sb.AddComment("Language", targetSymbol.Language);
+ sb.AddComment("DeclaredAccessibility", targetSymbol.DeclaredAccessibility);
+ sb.AddComment("ContainingSymbol Kind", targetSymbol.ContainingSymbol?.Kind);
+ sb.AddComment("ContainingSymbol Name", targetSymbol.ContainingSymbol?.Name);
+ sb.AddComment("ContainingAssembly Name", targetSymbol.ContainingAssembly?.Name);
+ sb.AddComment("ContainingModule Name", targetSymbol.ContainingModule?.Name);
+ sb.AddComment("ContainingType Name", targetSymbol.ContainingType?.Name);
+ var containingTypeTypeParameters = targetSymbol.ContainingType?.TypeParameters;
+ sb.AddComment("ContainingType Generic Types", containingTypeTypeParameters?.Length);
+ if (containingTypeTypeParameters != null)
+ {
+ for (var n = 0; n < containingTypeTypeParameters.Value.Length; n++)
+ {
+ var typeParameter = containingTypeTypeParameters.Value[n];
+ sb.AddComment($"ContainingType Generic Type {n+1}", typeParameter.ToDisplayString());
+ }
+ }
+ sb.AddComment("ContainingNamespace Name", targetSymbol.ContainingNamespace.Name);
+ sb.AddComment("ContainingNamespace IsGlobalNamespace", targetSymbol.ContainingNamespace.IsGlobalNamespace);
+ sb.AddComment("Name", targetSymbol.Name);
+ sb.AddComment("MetadataName", targetSymbol.MetadataName);
+ sb.AddComment("MetadataToken", targetSymbol.MetadataToken);
+ sb.AddComment("IsDefinition", targetSymbol.IsDefinition);
+ sb.AddComment("IsStatic", targetSymbol.IsStatic);
+ sb.AddComment("IsVirtual", targetSymbol.IsVirtual);
+ sb.AddComment("IsOverride", targetSymbol.IsOverride);
+ sb.AddComment("IsAbstract", targetSymbol.IsAbstract);
+ sb.AddComment("IsSealed", targetSymbol.IsSealed);
+ sb.AddComment("IsExtern", targetSymbol.IsExtern);
+ sb.AddComment("IsImplicitlyDeclared", targetSymbol.IsImplicitlyDeclared);
+ sb.AddComment("CanBeReferencedByName", targetSymbol.CanBeReferencedByName);
+
+ TargetSymbolDocComments = sb.ToString();
+
+ sb.Clear();
+
+ if (generatorAttributeSyntaxContext.TargetSymbol is ITypeSymbol typeTargetSymbol)
+ {
+ sb.AddComment("TypeKind", typeTargetSymbol.TypeKind);
+ sb.AddComment("BaseType Name", typeTargetSymbol.BaseType?.Name ?? string.Empty);
+ var interfaces = typeTargetSymbol.Interfaces;
+ sb.AddComment("Interfaces Length", interfaces.Length);
+ for (var n = 0; n < interfaces.Length; n++)
+ {
+ var directInterface = interfaces[n];
+ sb.AddComment($"Interface {n+1}", directInterface.ToDisplayString());
+ }
+ var allInterfaces = typeTargetSymbol.AllInterfaces;
+ sb.AddComment("AllInterfaces Length", allInterfaces.Length);
+ for (var n = 0; n < allInterfaces.Length; n++)
+ {
+ var implementedInterface = allInterfaces[n];
+ sb.AddComment($"Interface {n+1}", implementedInterface.ToDisplayString());
+ }
+ sb.AddComment("IsReferenceType", typeTargetSymbol.IsReferenceType);
+ sb.AddComment("IsValueType", typeTargetSymbol.IsValueType);
+ sb.AddComment("IsAnonymousType", typeTargetSymbol.IsAnonymousType);
+ sb.AddComment("IsTupleType", typeTargetSymbol.IsTupleType);
+ sb.AddComment("IsNativeIntegerType", typeTargetSymbol.IsNativeIntegerType);
+ sb.AddComment("SpecialType", typeTargetSymbol.SpecialType);
+ sb.AddComment("IsRefLikeType", typeTargetSymbol.IsRefLikeType);
+ sb.AddComment("IsUnmanagedType", typeTargetSymbol.IsUnmanagedType);
+ sb.AddComment("IsReadOnly", typeTargetSymbol.IsReadOnly);
+ sb.AddComment("IsRecord", typeTargetSymbol.IsRecord);
+ sb.AddComment("NullableAnnotation", typeTargetSymbol.NullableAnnotation);
+
+ TypeSymbolDocComments = sb.ToString();
+
+ sb.Clear();
+ }
+ else
+ {
+ TypeSymbolDocComments = string.Empty;
+ }
+
+ if (generatorAttributeSyntaxContext.TargetSymbol is INamedTypeSymbol namedTypeTargetSymbol)
+ {
+ var typeParameters = namedTypeTargetSymbol.TypeParameters.Select(tp => tp.Name).ToArray();
+ sb.AddComment("Arity", namedTypeTargetSymbol.Arity);
+ sb.AddComment("IsGenericType", namedTypeTargetSymbol.IsGenericType);
+ sb.AddComment("IsUnboundGenericType", namedTypeTargetSymbol.IsUnboundGenericType);
+ sb.AddComment("IsScriptClass", namedTypeTargetSymbol.IsScriptClass);
+ sb.AddComment("IsImplicitClass", namedTypeTargetSymbol.IsImplicitClass);
+ sb.AddComment("IsComImport", namedTypeTargetSymbol.IsComImport);
+ sb.AddComment("IsFileLocal", namedTypeTargetSymbol.IsFileLocal);
+ sb.AddComment("MemberNames", namedTypeTargetSymbol.MemberNames.Count());
+ sb.AddComment("TypeParameters", typeParameters.Length);
+ for (var n = 0; n < typeParameters.Length; n++)
+ {
+ var typeParameter = typeParameters[n];
+ sb.AddComment($"TypeParameter {n+1}", typeParameter);
+ }
+ sb.AddComment("InstanceConstructors", namedTypeTargetSymbol.InstanceConstructors.Length);
+ sb.AddComment("StaticConstructors", namedTypeTargetSymbol.StaticConstructors.Length);
+ sb.AddComment("MightContainExtensionMethods", namedTypeTargetSymbol.MightContainExtensionMethods);
+ sb.AddComment("IsSerializable", namedTypeTargetSymbol.IsSerializable);
+
+ NamedTypeSymbolDocComments = sb.ToString();
+
+ sb.Clear();
+ }
+ else
+ {
+ NamedTypeSymbolDocComments = string.Empty;
+ }
+
+ var targetNode = generatorAttributeSyntaxContext.TargetNode;
+ sb.AddComment("Type", targetNode.GetType().Name);
+ sb.AddComment("RawKind", targetNode.RawKind);
+ sb.AddComment("Kind", targetNode.Kind());
+ sb.AddComment("Language", targetNode.Language);
+ sb.AddComment("Span.Start", targetNode.Span.Start);
+ sb.AddComment("Span.Length", targetNode.Span.Length);
+ sb.AddComment("ContainsAnnotations", targetNode.ContainsAnnotations);
+ sb.AddComment("ContainsDiagnostics", targetNode.ContainsDiagnostics);
+ sb.AddComment("ContainsDirectives", targetNode.ContainsDirectives);
+ sb.AddComment("ContainsSkippedText", targetNode.ContainsSkippedText);
+ sb.AddComment("IsMissing", targetNode.IsMissing);
+ sb.AddComment("HasLeadingTrivia", targetNode.HasLeadingTrivia);
+ sb.AddComment("HasStructuredTrivia", targetNode.HasStructuredTrivia);
+ sb.AddComment("HasTrailingTrivia", targetNode.HasTrailingTrivia);
+ sb.AddComment("IsStructuredTrivia", targetNode.IsStructuredTrivia);
+
+
+ TargetNodeDocComments = sb.ToString();
+
+ sb.Clear();
+
+ Flags = AddAttributes(sb, generatorAttributeSyntaxContext.Attributes, true);
+
+ AttributesDocComments = sb.ToString();
+
+ sb.Clear();
+
+ AddAttributes(sb, targetSymbol.GetAttributes(), false);
+
+ AllAttributesDocComments = sb.ToString();
+
+ sb.Clear();
+ }
+
+ private static IncludeFlags AddAttributes(StringBuilder sb, ImmutableArray attributes, bool capture)
+ {
+ var flags = IncludeFlags.Summary;
+
+ sb.AddComment("Attribute Count", attributes.Length);
+ for (var i = 0; i < attributes.Length; i++)
+ {
+ var attribute = attributes[i];
+ sb.AddComment($"[{i}] AttributeClass", attribute.AttributeClass?.ToDisplayString());
+
+ var constructorArguments = attribute.ConstructorArguments;
+ var constructorArgumentsLength = constructorArguments.Length;
+ sb.AddComment($"[{i}] ConstructorArguments Count", constructorArgumentsLength);
+ for (var c = 0; c < constructorArgumentsLength; c++)
+ {
+ var constructorArgument = constructorArguments[c];
+ var attributeName = attribute.AttributeConstructor?.Parameters[c].Name;
+ sb.AddComment($"[{i}] AttributeConstructor Parameters {c+1} Name", attributeName);
+ sb.AddComment($"[{i}] ConstructorArgument {c+1} Kind", constructorArgument.Kind);
+ sb.AddComment($"[{i}] ConstructorArgument {c+1} Type", constructorArgument.Type?.Name);
+ sb.AddComment($"[{i}] ConstructorArgument {c+1} Value", constructorArgument.Value);
+
+ if (capture)
+ {
+ if (constructorArgument.Type?.Name == "IncludeFlags" && constructorArgument.Value != null)
+ {
+ flags |= (IncludeFlags)constructorArgument.Value;
+ }
+ else
+ {
+ // if we're looking at the example of named arguments, include the attribute details
+ flags = IncludeFlags.AttributeContextAttributes;
+ }
+ }
+ }
+
+ var namedArguments = attribute.NamedArguments;
+ var namedArgumentsLength = namedArguments.Length;
+ sb.AddComment($"[{i}] NamedArguments Count", namedArgumentsLength);
+ for (var n = 0; n < namedArgumentsLength; n++)
+ {
+ var kvp = namedArguments[n];
+ var argName = kvp.Key;
+ var namedArgument = kvp.Value;
+ sb.AddComment($"[{i}] NamedArgument {n+1} Key", argName);
+ sb.AddComment($"[{i}] NamedArgument {n+1} Value Kind", namedArgument.Kind);
+ sb.AddComment($"[{i}] NamedArgument {n+1} Value Type", namedArgument.Type?.Name);
+ sb.AddComment($"[{i}] NamedArgument {n+1} Value Value", namedArgument.Value);
+ if (capture)
+ {
+ // if we're looking at the example of named arguments, include the attribute details
+ flags = IncludeFlags.AttributeContextAttributes;
+ }
+ }
+ }
+
+ return flags;
+ }
+
+
+ public static AttributeData Collector(GeneratorAttributeSyntaxContext generatorAttributeSyntaxContext) => new(generatorAttributeSyntaxContext);
+}
\ No newline at end of file
diff --git a/SourceGeneratorContext/CodeGenerator.cs b/SourceGeneratorContext/CodeGenerator.cs
index 7ea8893..3a59aa9 100644
--- a/SourceGeneratorContext/CodeGenerator.cs
+++ b/SourceGeneratorContext/CodeGenerator.cs
@@ -1,318 +1,159 @@
-using System.Collections.Immutable;
-using System.Text;
-using Microsoft.CodeAnalysis;
+using Datacute.IncrementalGeneratorExtensions;
namespace Datacute.SourceGeneratorContext;
-public readonly struct CodeGenerator
+public class CodeGenerator : SourceTextGeneratorBase
{
public CodeGenerator(
in GeneratorSourceData source,
in CancellationToken cancellationToken)
+ : base(source.AttributeContext, cancellationToken)
{
- _attributeContext = source.Core.AttributeOptionsCompilationAndParseOptions.AttributeOptionsAndCompilation.AttributeAndOptions.AttributeContext;
- _globalOptionsDescription = source.Core.AttributeOptionsCompilationAndParseOptions.AttributeOptionsAndCompilation.AttributeAndOptions.Options;
- _compilationDescription = source.Core.AttributeOptionsCompilationAndParseOptions.AttributeOptionsAndCompilation.Compilation;
- _parseOptionsDescription = source.Core.AttributeOptionsCompilationAndParseOptions.ParseOptions;
- _additionalTextDescriptions = source.Core.AdditionalTexts;
- _metadataReferenceDescriptions = source.MetadataReferences;
- _cancellationToken = cancellationToken;
- _buffer = new StringBuilder();
+ // deconstruct the source data
+ (
+ var contextAndData,
+ _globalOptionsDescription,
+ _compilationDescription,
+ _parseOptionsDescription,
+ _additionalTextDescriptions,
+ _metadataReferenceDescriptions
+ ) = source;
+
+ _contextData = contextAndData.AttributeData;
}
- private readonly AttributeContext _attributeContext;
+ private readonly AttributeData _contextData;
+
private readonly AnalyzerConfigOptionsDescription _globalOptionsDescription;
private readonly CompilationDescription _compilationDescription;
private readonly ParseOptionsDescription _parseOptionsDescription;
- private readonly ImmutableArray _additionalTextDescriptions;
- private readonly ImmutableArray _metadataReferenceDescriptions;
- private readonly CancellationToken _cancellationToken;
-
- private readonly StringBuilder _buffer;
-
- public string GenerateSource()
- {
- _cancellationToken.ThrowIfCancellationRequested();
- _buffer.Clear();
- AutoGeneratedComment();
- StartNamespace();
- var indentLevel = ParentClasses();
- ClassDocComments(indentLevel);
- PartialTypeDeclaration(indentLevel);
- AppendStartClass(indentLevel);
- AppendEndClass(indentLevel);
- EndParentClasses();
- AppendDiagnosticLogs();
- return _buffer.ToString();
- }
-
- private void AutoGeneratedComment()
- {
- _buffer.AppendLine(Templates.AutoGeneratedComment);
- }
+ private readonly EquatableImmutableArray _additionalTextDescriptions;
+ private readonly EquatableImmutableArray _metadataReferenceDescriptions;
- private void StartNamespace()
+ protected override void AppendDocComments()
{
- if (_attributeContext.ContainingNamespaceIsGlobalNamespace) return;
+ Buffer.AppendLines(Templates.ClassDocCommentsBegin);
- _buffer.Append("namespace ");
- _buffer.Append(_attributeContext.ContainingNamespaceDisplayString);
- _buffer.Append(';').AppendLine();
- }
-
- private int ParentClasses()
- {
- var indentLevel = 0;
- if (_attributeContext.HasParentClasses)
+ if (_contextData.IncludeAttributeContextTargetSymbol || _contextData.IncludeSummary)
{
- indentLevel = StartParentClasses();
+ Buffer.AppendFormatLines(Templates.ClassDocCommentsSectionBegin, "GeneratorAttributeSyntaxContext TargetSymbol");
+ Buffer.AppendLines(_contextData.TargetSymbolDocComments);
+ Buffer.AppendLine(Templates.ClassDocCommentsSectionEnd);
}
- return indentLevel;
- }
- private int StartParentClasses()
- {
- var indent = 0;
- foreach (var parentClass in _attributeContext.ParentClasses)
+ if (_contextData.IncludeAttributeContextTypeSymbol && !string.IsNullOrEmpty(_contextData.TypeSymbolDocComments))
{
- _buffer.Append(' ', indent);
-
- // Use the parent's actual accessibility
- var accessibilityModifier = GetAccessibility(parentClass.Accessibility);
- // Include static modifier if the parent class is static
- var staticModifier = parentClass.IsStatic ? "static " : "";
- var genericTypes = parentClass.TypeParameters.Any()
- ? $"<{string.Join(",", parentClass.TypeParameters)}>"
- : string.Empty;
- _buffer.AppendLine($"{accessibilityModifier}{staticModifier}partial {parentClass.RecordStructOrClass} {parentClass.Name}{genericTypes}");
-
- _buffer.Append(' ', indent);
- _buffer.AppendLine("{");
- indent += 4;
+ Buffer.AppendFormatLines(Templates.ClassDocCommentsSectionBegin, "GeneratorAttributeSyntaxContext TargetSymbol as ITypeSymbol");
+ Buffer.AppendLines(_contextData.TypeSymbolDocComments);
+ Buffer.AppendLine(Templates.ClassDocCommentsSectionEnd);
}
- return indent;
- }
- private void ClassDocComments(int indent = 0)
- {
- var indentString = StringForIndent(indent);
- _buffer.AppendFormat(Templates.ClassDocCommentsBegin, indentString);
-
- if (_attributeContext.IncludeAttributeContextTargetSymbol || _attributeContext.IncludeAll || _attributeContext.IncludeSummary)
- {
- _buffer.AppendFormat(Templates.ClassDocCommentsSectionBegin, indentString, "GeneratorAttributeSyntaxContext TargetSymbol");
- AppendIndentedLines(indent, _attributeContext.TargetSymbolDocComments);
- _buffer.AppendFormat(Templates.ClassDocCommentsSectionEnd, indentString);
- }
-
- if ((_attributeContext.IncludeAttributeContextTypeSymbol || _attributeContext.IncludeAll) && !string.IsNullOrEmpty(_attributeContext.TypeSymbolDocComments))
- {
- _buffer.AppendFormat(Templates.ClassDocCommentsSectionBegin, indentString, "GeneratorAttributeSyntaxContext TargetSymbol as ITypeSymbol");
- AppendIndentedLines(indent,_attributeContext.TypeSymbolDocComments);
- _buffer.AppendFormat(Templates.ClassDocCommentsSectionEnd, indentString);
- }
-
- if ((_attributeContext.IncludeAttributeContextNamedTypeSymbol || _attributeContext.IncludeAll) && !string.IsNullOrEmpty(_attributeContext.NamedTypeSymbolDocComments))
+ if (_contextData.IncludeAttributeContextNamedTypeSymbol && !string.IsNullOrEmpty(_contextData.NamedTypeSymbolDocComments))
{
- _buffer.AppendFormat(Templates.ClassDocCommentsSectionBegin, indentString, "GeneratorAttributeSyntaxContext TargetSymbol as INamedTypeSymbol");
- AppendIndentedLines(indent, _attributeContext.NamedTypeSymbolDocComments);
- _buffer.AppendFormat(Templates.ClassDocCommentsSectionEnd, indentString);
+ Buffer.AppendFormatLines(Templates.ClassDocCommentsSectionBegin, "GeneratorAttributeSyntaxContext TargetSymbol as INamedTypeSymbol");
+ Buffer.AppendLines(_contextData.NamedTypeSymbolDocComments);
+ Buffer.AppendLine(Templates.ClassDocCommentsSectionEnd);
}
- if (_attributeContext.IncludeAttributeContextTargetNode || _attributeContext.IncludeAll)
+ if (_contextData.IncludeAttributeContextTargetNode)
{
- _buffer.AppendFormat(Templates.ClassDocCommentsSectionBegin, indentString, "GeneratorAttributeSyntaxContext TargetNode");
- AppendIndentedLines(indent, _attributeContext.TargetNodeDocComments);
- _buffer.AppendFormat(Templates.ClassDocCommentsSectionEnd, indentString);
+ Buffer.AppendFormatLines(Templates.ClassDocCommentsSectionBegin, "GeneratorAttributeSyntaxContext TargetNode");
+ Buffer.AppendLines(_contextData.TargetNodeDocComments);
+ Buffer.AppendLine(Templates.ClassDocCommentsSectionEnd);
}
- if (_attributeContext.IncludeAttributeContextAttributes || _attributeContext.IncludeAll)
+ if (_contextData.IncludeAttributeContextAttributes)
{
- _buffer.AppendFormat(Templates.ClassDocCommentsSectionBegin, indentString, "GeneratorAttributeSyntaxContext Attributes");
- AppendIndentedLines(indent, _attributeContext.AttributesDocComments);
- _buffer.AppendFormat(Templates.ClassDocCommentsSectionEnd, indentString);
+ Buffer.AppendFormatLines(Templates.ClassDocCommentsSectionBegin, "GeneratorAttributeSyntaxContext Attributes");
+ Buffer.AppendLines(_contextData.AttributesDocComments);
+ Buffer.AppendLine(Templates.ClassDocCommentsSectionEnd);
}
- if (_attributeContext.IncludeAttributeContextAllAttributes || _attributeContext.IncludeAll)
+ if (_contextData.IncludeAttributeContextAllAttributes)
{
- _buffer.AppendFormat(Templates.ClassDocCommentsSectionBegin, indentString, "GeneratorAttributeSyntaxContext TargetSymbol AllAttributes()");
- AppendIndentedLines(indent, _attributeContext.AllAttributesDocComments);
- _buffer.AppendFormat(Templates.ClassDocCommentsSectionEnd, indentString);
+ Buffer.AppendFormatLines(Templates.ClassDocCommentsSectionBegin, "GeneratorAttributeSyntaxContext TargetSymbol AllAttributes()");
+ Buffer.AppendLines(_contextData.AllAttributesDocComments);
+ Buffer.AppendLine(Templates.ClassDocCommentsSectionEnd);
}
- if (_attributeContext.IncludeGlobalOptions || _attributeContext.IncludeAll)
+ if (_contextData.IncludeGlobalOptions)
{
- _buffer.AppendFormat(Templates.ClassDocCommentsSectionBegin, indentString, "AnalyzerConfigOptionsProvider GlobalOptions");
- AppendIndentedLines(indent, _globalOptionsDescription.DocComments);
- _buffer.AppendFormat(Templates.ClassDocCommentsSectionEnd, indentString);
+ Buffer.AppendFormatLines(Templates.ClassDocCommentsSectionBegin, "AnalyzerConfigOptionsProvider GlobalOptions");
+ Buffer.AppendLines(_globalOptionsDescription.DocComments);
+ Buffer.AppendLine(Templates.ClassDocCommentsSectionEnd);
}
- if (_attributeContext.IncludeCompilation || _attributeContext.IncludeAll)
+ if (_contextData.IncludeCompilation)
{
- _buffer.AppendFormat(Templates.ClassDocCommentsSectionBegin, indentString, "Compilation");
- AppendIndentedLines(indent, _compilationDescription.DocComments);
- _buffer.AppendFormat(Templates.ClassDocCommentsSectionEnd, indentString);
+ Buffer.AppendFormatLines(Templates.ClassDocCommentsSectionBegin, "Compilation");
+ Buffer.AppendLines(_compilationDescription.DocComments);
+ Buffer.AppendLine(Templates.ClassDocCommentsSectionEnd);
}
- if (_attributeContext.IncludeCompilationOptions || _attributeContext.IncludeAll)
+ if (_contextData.IncludeCompilationOptions)
{
- _buffer.AppendFormat(Templates.ClassDocCommentsSectionBegin, indentString, "Compilation Options");
- AppendIndentedLines(indent, _compilationDescription.OptionsDocComments);
- _buffer.AppendFormat(Templates.ClassDocCommentsSectionEnd, indentString);
+ Buffer.AppendFormatLines(Templates.ClassDocCommentsSectionBegin, "Compilation Options");
+ Buffer.AppendLines(_compilationDescription.OptionsDocComments);
+ Buffer.AppendLine(Templates.ClassDocCommentsSectionEnd);
}
- if (_attributeContext.IncludeCompilationAssembly || _attributeContext.IncludeAll)
+ if (_contextData.IncludeCompilationAssembly)
{
- _buffer.AppendFormat(Templates.ClassDocCommentsSectionBegin, indentString, "Compilation Assembly");
- AppendIndentedLines(indent, _compilationDescription.AssemblyDocComments);
- _buffer.AppendFormat(Templates.ClassDocCommentsSectionEnd, indentString);
+ Buffer.AppendFormatLines(Templates.ClassDocCommentsSectionBegin, "Compilation Assembly");
+ Buffer.AppendLines(_compilationDescription.AssemblyDocComments);
+ Buffer.AppendLine(Templates.ClassDocCommentsSectionEnd);
}
- if (_attributeContext.IncludeCompilationReferences || _attributeContext.IncludeAll)
+ if (_contextData.IncludeCompilationReferences)
{
- _buffer.AppendFormat(Templates.ClassDocCommentsSectionBegin, indentString, "Compilation References");
- AppendIndentedLines(indent, _compilationDescription.ReferencesDocComments);
- _buffer.AppendFormat(Templates.ClassDocCommentsSectionEnd, indentString);
+ Buffer.AppendFormatLines(Templates.ClassDocCommentsSectionBegin, "Compilation References");
+ Buffer.AppendLines(_compilationDescription.ReferencesDocComments);
+ Buffer.AppendLine(Templates.ClassDocCommentsSectionEnd);
}
- if (_attributeContext.IncludeParseOptions || _attributeContext.IncludeAll)
+ if (_contextData.IncludeParseOptions)
{
- _buffer.AppendFormat(Templates.ClassDocCommentsSectionBegin, indentString, "Parse Options");
- AppendIndentedLines(indent, _parseOptionsDescription.DocComments);
- _buffer.AppendFormat(Templates.ClassDocCommentsSectionEnd, indentString);
+ Buffer.AppendFormatLines(Templates.ClassDocCommentsSectionBegin, "Parse Options");
+ Buffer.AppendLines(_parseOptionsDescription.DocComments);
+ Buffer.AppendLine(Templates.ClassDocCommentsSectionEnd);
}
- if (_attributeContext.IncludeAdditionalTexts || _attributeContext.IncludeAll)
+ if (_contextData.IncludeAdditionalTexts)
{
- _buffer.AppendFormat(Templates.ClassDocCommentsSectionBegin, indentString, "Additional Texts");
- // todo: indent
- _buffer.AddComment("Number of Additional Texts", _additionalTextDescriptions.Length);
+ Buffer.AppendFormatLines(Templates.ClassDocCommentsSectionBegin, "Additional Texts");
+ Buffer.AddComment("Number of Additional Texts", _additionalTextDescriptions.Length);
foreach (var additionalTextDescription in _additionalTextDescriptions)
{
- AppendIndentedLines(indent, additionalTextDescription.DocComments);
- if (_attributeContext.IncludeAdditionalTextsOptions)
+ Buffer.AppendLines(additionalTextDescription.DocComments);
+ if (_contextData.IncludeAdditionalTextsOptions)
{
- AppendIndentedLines(indent, additionalTextDescription.OptionsComments);
+ Buffer.AppendLines(additionalTextDescription.OptionsComments);
}
}
- _buffer.AppendFormat(Templates.ClassDocCommentsSectionEnd, indentString);
+ Buffer.AppendLine(Templates.ClassDocCommentsSectionEnd);
}
- if (_attributeContext.IncludeMetadataReferences || _attributeContext.IncludeAll)
+ if (_contextData.IncludeMetadataReferences)
{
- _buffer.AppendFormat(Templates.ClassDocCommentsSectionBegin, indentString, "Metadata References");
- // todo: indent
- _buffer.AddComment("Number of Metadata References", _metadataReferenceDescriptions.Length);
- foreach (var metadataReferenceDescription in _metadataReferenceDescriptions)
+ Buffer.AppendFormatLines(Templates.ClassDocCommentsSectionBegin, "Metadata References");
+ Buffer.AddComment("Number of Metadata References", _metadataReferenceDescriptions.Length);
+ if (_metadataReferenceDescriptions.Length > 0)
{
- AppendIndentedLines(indent, metadataReferenceDescription.DocComments);
+ Buffer.AddComment("Properties Kind, EmbedInteropTypes, Aliases", "[Skipped for brevity]");
}
- _buffer.AppendFormat(Templates.ClassDocCommentsSectionEnd, indentString);
- }
-
- _buffer.AppendFormat(Templates.ClassDocCommentsEnd, indentString);
- }
-
- private void PartialTypeDeclaration(int indent = 0)
- {
- var genericTypes = _attributeContext.TypeParameters.Any()
- ? $"<{string.Join(",", _attributeContext.TypeParameters)}>"
- : string.Empty;
- _buffer.Append(' ', indent);
- _buffer.AppendFormat(
- "{0}{1}partial {2} {3}{4}",
- GetAccessibility(),
- GetStatic(),
- _attributeContext.RecordStructOrClass,
- _attributeContext.Name,
- genericTypes
- ).AppendLine();
- }
-
- private string GetAccessibility()
- {
- var accessibility = _attributeContext.DeclaredAccessibility;
- return GetAccessibility(accessibility);
- }
-
- private static string GetAccessibility(Accessibility accessibility)
- {
- return accessibility switch
- {
- Accessibility.Private => "private ",
- Accessibility.ProtectedAndInternal => "private protected ",
- Accessibility.Protected => "protected ",
- Accessibility.Internal => "internal ",
- Accessibility.ProtectedOrInternal => "protected internal ",
- Accessibility.Public => "public ",
- _ => throw new ArgumentOutOfRangeException(nameof(accessibility), accessibility, null)
- };
- }
-
- private string GetStatic() => _attributeContext.IsStatic ? "static " : "";
-
- private void AppendStartClass(int indent = 0)
- {
- var indentString = StringForIndent(indent);
- _buffer.Append(indentString);
- _buffer.AppendLine("{");
- }
-
-
- private void AppendEndClass(int indent = 0)
- {
- var indentString = StringForIndent(indent);
- _buffer.Append(indentString);
- _buffer.AppendLine("}");
- }
-
- private void EndParentClasses()
- {
- // Close parent classes if any
- if (_attributeContext.HasParentClasses)
- {
- var indent = (_attributeContext.ParentClasses.Length - 1) * 4;
- for (int i = 0; i < _attributeContext.ParentClasses.Length; i++)
+ foreach (var metadataReferenceDescription in _metadataReferenceDescriptions)
{
- AppendEndClass(indent);
- indent -= 4;
+ Buffer.AppendLines(metadataReferenceDescription.DocComments);
}
+ Buffer.AppendLine(Templates.ClassDocCommentsSectionEnd);
}
- }
- private void AppendDiagnosticLogs()
- {
- _buffer.AppendLine();
- _buffer.AppendLine("/* Diagnostic Log");
- LightweightTrace.Add(TrackingNames.DiagnosticLog_Written);
- LightweightTrace.GetTrace(_buffer, TrackingNames.TracingNames);
- _buffer.AppendLine("*/");
+ Buffer.AppendLine(Templates.ClassDocCommentsEnd);
}
-
- private static readonly Dictionary IndentationCache = new();
- private string StringForIndent(int indent)
+
+ protected override void AppendDiagnosticLogs()
{
- if (!IndentationCache.TryGetValue(indent, out var indentString))
- {
- indentString = new string(' ', indent);
- IndentationCache[indent] = indentString;
- }
- return indentString;
- }
-
- private void AppendIndentedLines(int indent, string lines)
- {
- var indentString = StringForIndent(indent);
- bool includeLineBreak = false;
- foreach (var line in lines.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries))
- {
- if (includeLineBreak)
- {
- _buffer.AppendLine();
- }
- _buffer.Append(indentString);
- _buffer.Append(line);
- includeLineBreak = true;
- }
+ Buffer.AppendLine();
+ Buffer.Direct.AppendDiagnosticsComment(GeneratorStageDescriptions.GeneratorStageNameMap);
}
}
diff --git a/SourceGeneratorContext/CompilationDescription.cs b/SourceGeneratorContext/CompilationDescription.cs
index 66b21c0..ea0db0a 100644
--- a/SourceGeneratorContext/CompilationDescription.cs
+++ b/SourceGeneratorContext/CompilationDescription.cs
@@ -127,10 +127,8 @@ public CompilationDescription(Compilation compilation)
// SyntaxTreesDocComments = sb.ToString();
}
- public static CompilationDescription Select(Compilation compilation, CancellationToken token)
+ public static CompilationDescription Selector(Compilation compilation, CancellationToken token)
{
- LightweightTrace.Add(TrackingNames.CompilationDescription_Select);
-
token.ThrowIfCancellationRequested();
return new CompilationDescription(compilation);
}
diff --git a/SourceGeneratorContext/DocCommentDescriptionExtensions.cs b/SourceGeneratorContext/DocCommentDescriptionExtensions.cs
index 001b5b3..b25f258 100644
--- a/SourceGeneratorContext/DocCommentDescriptionExtensions.cs
+++ b/SourceGeneratorContext/DocCommentDescriptionExtensions.cs
@@ -1,4 +1,5 @@
using System.Text;
+using Datacute.IncrementalGeneratorExtensions;
namespace Datacute.SourceGeneratorContext;
@@ -10,4 +11,11 @@ public static void AddComment(this StringBuilder sb, string propertyName, object
var valueString = value.ToString();
sb.AppendFormat(Templates.OptionsLine, propertyName, Templates.EscapeStringForDocComments(valueString));
}
+
+ public static void AddComment(this IndentingLineAppender sb, string propertyName, object? value)
+ {
+ if (value == null) return;
+ var valueString = value.ToString();
+ sb.AppendFormatLines(Templates.OptionsLine, propertyName, Templates.EscapeStringForDocComments(valueString));
+ }
}
\ No newline at end of file
diff --git a/SourceGeneratorContext/EquatableImmutableArray.cs b/SourceGeneratorContext/EquatableImmutableArray.cs
deleted file mode 100644
index 4b01eb9..0000000
--- a/SourceGeneratorContext/EquatableImmutableArray.cs
+++ /dev/null
@@ -1,211 +0,0 @@
-using System.Collections;
-using System.Collections.Concurrent;
-using System.Collections.Immutable;
-using Microsoft.CodeAnalysis;
-
-namespace Datacute.SourceGeneratorContext;
-
-public sealed class EquatableImmutableArray : IEquatable>, IReadOnlyList
- where T : IEquatable
-{
- public static EquatableImmutableArray Empty { get; } = new(ImmutableArray.Empty);
-
- // The source generation pipelines compare these a lot
- // so being able to quickly tell when they are different
- // is important.
- // We will use an instance cache to find when we can reuse
- // an existing object, massively speeding up the Equals call.
- #region Instance Cache
-
- // Thread-safe cache using dictionary of hash code -> list of arrays with that hash
- private static readonly ConcurrentDictionary>>> InstanceCache = new();
-
- // Static factory method with singleton handling
- public static EquatableImmutableArray Create(ImmutableArray values, CancellationToken cancellationToken = default)
- {
- if (values.IsEmpty)
- return Empty;
-
- // Calculate hash code for the values
- var hash = CalculateHashCode(values);
-
- // Try to find an existing instance with the same hash and values
- if (InstanceCache.TryGetValue(hash, out var list))
- {
- cancellationToken.ThrowIfCancellationRequested();
-
- lock (list) // Thread safety for the list
- {
- for (int i = list.Count - 1; i >= 0; i--)
- {
- cancellationToken.ThrowIfCancellationRequested();
-
- if (list[i].TryGetTarget(out var existing))
- {
- // Element-by-element comparison for arrays with the same hash
- if (ValuesEqual(values, existing._values))
- return existing;
- }
- else
- {
- // Remove dead references
- list.RemoveAt(i);
- }
- }
- }
- }
-
- // Create new instance and add to cache
- var result = new EquatableImmutableArray(values, hash);
-
- InstanceCache.AddOrUpdate(hash,
- _ => new List>> { new(result) },
- (_, existingList) =>
- {
- cancellationToken.ThrowIfCancellationRequested();
- lock (existingList)
- {
- existingList.Add(new WeakReference>(result));
- }
- return existingList;
- });
-
- return result;
- }
-
- private static bool ValuesEqual(ImmutableArray a, ImmutableArray b)
- {
- // Identical arrays reference check
- if (a == b) return true;
-
- int length = a.Length;
- if (length != b.Length) return false;
-
- var comparer = EqualityComparer.Default;
- for (int i = 0; i < length; i++)
- {
- if (!comparer.Equals(a[i], b[i]))
- return false;
- }
-
- return true;
- }
-
- private static int CalculateHashCode(ImmutableArray values)
- {
- var comparer = EqualityComparer.Default;
- var hash = 0;
- for (var index = 0; index < values.Length; index++)
- {
- var value = values[index];
- hash = HashHelpers_Combine(hash, value is null ? 0 : comparer.GetHashCode(value));
- }
- return hash;
- }
-
- #endregion
-
- private readonly ImmutableArray _values;
- private readonly int _hashCode;
- private readonly int _length;
- public T this[int index] => _values[index];
- public int Count => _length;
-
- private EquatableImmutableArray(ImmutableArray values)
- {
- _values = values;
- _length = values.Length;
- _hashCode = CalculateHashCode(values);
- }
-
- private EquatableImmutableArray(ImmutableArray values, int hashCode)
- {
- _values = values;
- _length = values.Length;
- _hashCode = hashCode;
- }
-
- public bool Equals(EquatableImmutableArray? other)
- {
- // Fast reference equality check
- if (ReferenceEquals(this, other)) return true;
-
- if (other is null) return false;
-
- // If hash codes are different, arrays can't be equal
- if (_hashCode != other._hashCode)
- return false;
-
- // We're really unlikely to get here, as we're using an instance cache
- // so we've probably encountered a hash collision
-
- // Compare array lengths
- if (_length != other._length) return false;
-
- // If both are empty, they're equal
- if (_length == 0) return true;
-
- // Element-by-element comparison
- var comparer = EqualityComparer.Default;
- for (int i = 0; i < _length; i++)
- {
- if (!comparer.Equals(_values[i], other._values[i]))
- return false;
- }
-
- return true;
- }
-
- public override bool Equals(object? obj) => obj is EquatableImmutableArray other && Equals(other);
-
- public override int GetHashCode() => _hashCode;
-
- private static int HashHelpers_Combine(int h1, int h2)
- {
- // RyuJIT optimizes this to use the ROL instruction
- // Related GitHub pull request: https://github.com/dotnet/coreclr/pull/1830
- uint rol5 = ((uint)h1 << 5) | ((uint)h1 >> 27);
- return ((int)rol5 + h1) ^ h2;
- }
-
- IEnumerator IEnumerable.GetEnumerator() => ((IEnumerable)_values).GetEnumerator();
- IEnumerator IEnumerable.GetEnumerator() => ((IEnumerable)_values).GetEnumerator();
-}
-
-public static class EquatableImmutableArrayExtensions
-{
- public static EquatableImmutableArray ToEquatableImmutableArray(this ImmutableArray values, Func selector, CancellationToken ct = default) where T : IEquatable
- {
- var builder = ImmutableArray.CreateBuilder(values.Length);
- foreach (TSource value in values)
- {
- builder.Add(selector(value));
- }
- return EquatableImmutableArray.Create(builder.MoveToImmutable(), ct);
- }
- public static EquatableImmutableArray ToEquatableImmutableArray(this EquatableImmutableArray values, Func selector, CancellationToken ct = default) where TSource : IEquatable where T : IEquatable
- {
- var builder = ImmutableArray.CreateBuilder(values.Count);
- foreach (TSource value in values)
- {
- builder.Add(selector(value));
- }
- return EquatableImmutableArray.Create(builder.MoveToImmutable(), ct);
- }
- public static EquatableImmutableArray ToEquatableImmutableArray(this IEnumerable values, CancellationToken ct = default) where T : IEquatable => EquatableImmutableArray.Create(values.ToImmutableArray(), ct);
-
- public static EquatableImmutableArray ToEquatableImmutableArray(this ImmutableArray values, CancellationToken ct = default) where T : IEquatable => EquatableImmutableArray.Create(values, ct);
-
- public static IncrementalValuesProvider<(TLeft Left, EquatableImmutableArray Right)> CombineEquatable(
- this IncrementalValuesProvider provider1,
- IncrementalValuesProvider provider2)
- where TRight : IEquatable
- => provider1.Combine(provider2.Collect().Select(EquatableImmutableArray.Create));
-
- public static IncrementalValueProvider<(TLeft Left, EquatableImmutableArray Right)> CombineEquatable(
- this IncrementalValueProvider provider1,
- IncrementalValuesProvider provider2)
- where TRight : IEquatable
- => provider1.Combine(provider2.Collect().Select(EquatableImmutableArray.Create));
-
-}
diff --git a/SourceGeneratorContext/Generator.cs b/SourceGeneratorContext/Generator.cs
index 98cc02d..57b2544 100644
--- a/SourceGeneratorContext/Generator.cs
+++ b/SourceGeneratorContext/Generator.cs
@@ -1,69 +1,88 @@
-using System.Collections.Immutable;
+using Datacute.IncrementalGeneratorExtensions;
using Microsoft.CodeAnalysis;
namespace Datacute.SourceGeneratorContext;
-// Record structs to replace complex tuple types
-public record struct AttributeAndOptions(AttributeContext AttributeContext, AnalyzerConfigOptionsDescription Options);
-public record struct AttributeOptionsAndCompilation(AttributeAndOptions AttributeAndOptions, CompilationDescription Compilation);
-public record struct AttributeOptionsCompilationAndParseOptions(AttributeOptionsAndCompilation AttributeOptionsAndCompilation, ParseOptionsDescription ParseOptions);
-public record struct AttributeOptionsCompilationParseAndAdditionalTexts(AttributeOptionsCompilationAndParseOptions AttributeOptionsCompilationAndParseOptions, ImmutableArray AdditionalTexts);
-public record struct GeneratorSourceData(AttributeOptionsCompilationParseAndAdditionalTexts Core, ImmutableArray MetadataReferences);
-
[Generator(LanguageNames.CSharp)]
public sealed class Generator : IIncrementalGenerator
{
public void Initialize(IncrementalGeneratorInitializationContext context)
{
- LightweightTrace.Add(TrackingNames.Generator_Initialize);
+ LightweightTrace.Add(GeneratorStage.Initialize);
+
+ context.RegisterPostInitializationOutput(static postInitializationContext =>
+ {
+ LightweightTrace.Add(GeneratorStage.RegisterPostInitializationOutput);
+
+ postInitializationContext.AddSource(
+ Templates.IncludeFlagsHintName,
+ Templates.IncludeFlags);
+ postInitializationContext.AddSource(
+ Templates.AttributeHintName,
+ Templates.SourceGeneratorContextAttribute);
+ });
var attributeContexts =
- context.SyntaxProvider.ForAttributeWithMetadataName(
- fullyQualifiedMetadataName: Templates.AttributeFullyQualified,
- predicate: AttributeContext.Predicate,
- transform: AttributeContext.Transform)
- .WithTrackingName(TrackingNames.InitialExtraction);
+ context.SelectAttributeContexts(
+ Templates.AttributeFullyQualified,
+ AttributeData.Collector);
+
+ var globalOptionsDescriptionValueProvider =
+ context.AnalyzerConfigOptionsProvider
+ .Select(AnalyzerConfigOptionsDescription.Selector)
+ .WithTrackingName(GeneratorStage.AnalyzerConfigOptionsProviderSelect);
- var globalOptionsDescriptionValueProvider = context.AnalyzerConfigOptionsProvider.Select(AnalyzerConfigOptionsDescription.Select);
- var compilationDescriptionValueProvider = context.CompilationProvider.Select(CompilationDescription.Select);
- var parseOptionsDescriptionValueProvider = context.ParseOptionsProvider.Select(ParseOptionsDescription.Select);
+ var compilationDescriptionValueProvider =
+ context.CompilationProvider
+ .Select(CompilationDescription.Selector)
+ .WithTrackingName(GeneratorStage.CompilationProviderSelect);
- // It is possible to get config options FOR each additional text, but showing them is very repetitive
- var additionalTextDescriptionsValuesProvider = context.AdditionalTextsProvider.Combine(context.AnalyzerConfigOptionsProvider).Select(AdditionalTextDescription.Select);
- // var additionalTextDescriptionsValuesProvider = context.AdditionalTextsProvider.Select(AdditionalTextDescription.Select);
- var metadataReferenceDescriptionsValuesProvider = context.MetadataReferencesProvider.Select(MetadataReferenceDescription.Select);
+ var parseOptionsDescriptionValueProvider =
+ context.ParseOptionsProvider
+ .Select(ParseOptionsDescription.Selector)
+ .WithTrackingName(GeneratorStage.ParseOptionsProviderSelect);
+
+ var additionalTextDescriptionsValuesProvider =
+ context.AdditionalTextsProvider
+ .Combine(context.AnalyzerConfigOptionsProvider)
+ .Select(AdditionalTextDescription.Selector)
+ .WithTrackingName(GeneratorStage.AdditionalTextsProviderSelect);
+
+ var metadataReferenceDescriptionsValuesProvider =
+ context.MetadataReferencesProvider
+ .Select(MetadataReferenceDescription.Selector)
+ .WithTrackingName(GeneratorStage.MetadataReferencesProviderSelect);
var source = attributeContexts
.Combine(globalOptionsDescriptionValueProvider)
- .Select((x, _) => new AttributeAndOptions(x.Left, x.Right))
+ .Select(SourceBuilder.WithOptions)
.Combine(compilationDescriptionValueProvider)
- .Select((x, _) => new AttributeOptionsAndCompilation(x.Left, x.Right))
+ .Select(SourceBuilder.WithCompilation)
.Combine(parseOptionsDescriptionValueProvider)
- .Select((x, _) => new AttributeOptionsCompilationAndParseOptions(x.Left, x.Right))
- .Combine(additionalTextDescriptionsValuesProvider.Collect())
- .Select((x, _) => new AttributeOptionsCompilationParseAndAdditionalTexts(x.Left, x.Right))
- .Combine(metadataReferenceDescriptionsValuesProvider.Collect())
- .Select((x, _) => new GeneratorSourceData(x.Left, x.Right))
- .WithTrackingName(TrackingNames.Combine);
-
+ .Select(SourceBuilder.WithParseOptions)
+ .CombineEquatable(additionalTextDescriptionsValuesProvider)
+ .Select(SourceBuilder.WithAdditionalTexts)
+ .CombineEquatable(metadataReferenceDescriptionsValuesProvider)
+ .Select(SourceBuilder.WithMetadataReferences);
+
context.RegisterSourceOutput(source, Action);
}
- private void Action(SourceProductionContext sourceProductionContext, GeneratorSourceData source)
+ private void Action(SourceProductionContext sourceProductionContext, SourceBuilder source)
{
- LightweightTrace.Add(TrackingNames.Generator_Action);
+ LightweightTrace.Add(GeneratorStage.RegisterSourceOutput);
- var attributeContext = source.Core.AttributeOptionsCompilationAndParseOptions.AttributeOptionsAndCompilation.AttributeAndOptions.AttributeContext;
+ var attributeContext = source.AttributeContext;
var cancellationToken = sourceProductionContext.CancellationToken;
- cancellationToken.ThrowIfCancellationRequested();
+ cancellationToken.ThrowIfCancellationRequested(0);
+
+ var codeGenerator = new CodeGenerator(source.Build(), cancellationToken);
- var codeGenerator = new CodeGenerator(source, cancellationToken);
+ var hintName = attributeContext.CreateHintName("SourceGeneratorContext");
+ var generatedSource = codeGenerator.GetSourceText();
- var hintName = attributeContext.DisplayString.GetHintName();
- var generatedSource = codeGenerator.GenerateSource();
+ LightweightTrace.Add(GeneratorStage.SourceProductionContextAddSource);
sourceProductionContext.AddSource(hintName, generatedSource);
}
-
-
}
\ No newline at end of file
diff --git a/SourceGeneratorContext/GeneratorSourceData.cs b/SourceGeneratorContext/GeneratorSourceData.cs
new file mode 100644
index 0000000..1875847
--- /dev/null
+++ b/SourceGeneratorContext/GeneratorSourceData.cs
@@ -0,0 +1,11 @@
+using Datacute.IncrementalGeneratorExtensions;
+
+namespace Datacute.SourceGeneratorContext;
+
+public readonly record struct GeneratorSourceData(
+ AttributeContextAndData AttributeContext,
+ AnalyzerConfigOptionsDescription Options,
+ CompilationDescription Compilation,
+ ParseOptionsDescription ParseOptions,
+ EquatableImmutableArray AdditionalTexts,
+ EquatableImmutableArray MetadataReferences);
\ No newline at end of file
diff --git a/SourceGeneratorContext/IsExternalInit.cs b/SourceGeneratorContext/IsExternalInit.cs
new file mode 100644
index 0000000..94c788f
--- /dev/null
+++ b/SourceGeneratorContext/IsExternalInit.cs
@@ -0,0 +1,7 @@
+// ReSharper disable once CheckNamespace
+namespace System.Runtime.CompilerServices
+{
+ internal static class IsExternalInit
+ {
+ }
+}
\ No newline at end of file
diff --git a/SourceGeneratorContext/LightweightTracing/LightweightTrace.cs b/SourceGeneratorContext/LightweightTracing/LightweightTrace.cs
deleted file mode 100644
index 12eb47b..0000000
--- a/SourceGeneratorContext/LightweightTracing/LightweightTrace.cs
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (c) 2025 Stephen Denne
- * https://github.com/datacute/LightweightTracing
- */
-
-using System.Diagnostics;
-using System.Text;
-
-namespace Datacute.SourceGeneratorContext;
-
-public static class LightweightTrace
-{
- private const int Capacity = 1024;
-
- private static readonly DateTime StartTime = DateTime.UtcNow;
- private static readonly Stopwatch Stopwatch = Stopwatch.StartNew();
-
- private static readonly (long, int)[] Events = new (long, int)[Capacity];
- private static int _index;
-
- public static void Add(int eventId)
- {
- Events[_index] = (Stopwatch.ElapsedTicks, eventId);
- _index = (_index + 1) % Capacity;
- }
-
- public static void GetTrace(StringBuilder stringBuilder, Dictionary eventNameMap)
- {
- var index = _index;
- for (var i = 0; i < Capacity; i++)
- {
- var (timestamp, eventId) = Events[index];
- if (timestamp > 0)
- {
- stringBuilder.AppendFormat("{0:o} [{1:000}] {2}",
- StartTime.AddTicks(timestamp),
- eventId,
- eventNameMap.TryGetValue(eventId, out var name) ? name : string.Empty)
- .AppendLine();
- }
-
- index = (index + 1) % Capacity;
- }
- }
-}
\ No newline at end of file
diff --git a/SourceGeneratorContext/MetadataReferenceDescription.cs b/SourceGeneratorContext/MetadataReferenceDescription.cs
index a20a932..a0a2b53 100644
--- a/SourceGeneratorContext/MetadataReferenceDescription.cs
+++ b/SourceGeneratorContext/MetadataReferenceDescription.cs
@@ -3,10 +3,10 @@
namespace Datacute.SourceGeneratorContext;
-public readonly struct MetadataReferenceDescription
+public readonly record struct MetadataReferenceDescription
{
public readonly string DocComments;
- public MetadataReferenceDescription(MetadataReference metadataReference)
+ private MetadataReferenceDescription(MetadataReference metadataReference)
{
var sb = new StringBuilder();
sb.AddComment("Display", metadataReference.Display);
@@ -17,10 +17,8 @@ public MetadataReferenceDescription(MetadataReference metadataReference)
DocComments = sb.ToString();
}
- public static MetadataReferenceDescription Select(MetadataReference metadataReference, CancellationToken token)
+ public static MetadataReferenceDescription Selector(MetadataReference metadataReference, CancellationToken token)
{
- //LightweightTrace.Add(TrackingNames.MetadataReferenceDescription_Select);
-
token.ThrowIfCancellationRequested();
return new MetadataReferenceDescription(metadataReference);
}
diff --git a/SourceGeneratorContext/ParseOptionsDescription.cs b/SourceGeneratorContext/ParseOptionsDescription.cs
index 8f90729..856ca36 100644
--- a/SourceGeneratorContext/ParseOptionsDescription.cs
+++ b/SourceGeneratorContext/ParseOptionsDescription.cs
@@ -30,10 +30,8 @@ public ParseOptionsDescription(ParseOptions parseOptions)
DocComments = sb.ToString();
}
- public static ParseOptionsDescription Select(ParseOptions parseOptions, CancellationToken token)
+ public static ParseOptionsDescription Selector(ParseOptions parseOptions, CancellationToken token)
{
- LightweightTrace.Add(TrackingNames.ParseOptionsDescription_Select);
-
token.ThrowIfCancellationRequested();
return new ParseOptionsDescription(parseOptions);
}
diff --git a/SourceGeneratorContext/SourceBuilder.cs b/SourceGeneratorContext/SourceBuilder.cs
new file mode 100644
index 0000000..84133a7
--- /dev/null
+++ b/SourceGeneratorContext/SourceBuilder.cs
@@ -0,0 +1,48 @@
+using Datacute.IncrementalGeneratorExtensions;
+
+namespace Datacute.SourceGeneratorContext;
+
+public readonly record struct SourceBuilder(
+ AttributeContextAndData AttributeContext,
+ AnalyzerConfigOptionsDescription? Options,
+ CompilationDescription? Compilation,
+ ParseOptionsDescription? ParseOptions,
+ EquatableImmutableArray? AdditionalTexts,
+ EquatableImmutableArray? MetadataReferences)
+{
+ public static SourceBuilder WithOptions(
+ (AttributeContextAndData AttributeContext, AnalyzerConfigOptionsDescription Options) data,
+ CancellationToken _)
+ => new(data.AttributeContext, data.Options, null, null, null, null);
+
+ public static SourceBuilder WithCompilation(
+ (SourceBuilder previous, CompilationDescription Compilation) data,
+ CancellationToken _)
+ => data.previous with { Compilation = data.Compilation };
+
+ public static SourceBuilder WithParseOptions(
+ (SourceBuilder previous, ParseOptionsDescription ParseOptions) data,
+ CancellationToken _)
+ => data.previous with { ParseOptions = data.ParseOptions };
+
+ public static SourceBuilder WithAdditionalTexts(
+ (SourceBuilder previous, EquatableImmutableArray AdditionalTexts) data,
+ CancellationToken _)
+ => data.previous with { AdditionalTexts = data.AdditionalTexts };
+
+ public static SourceBuilder WithMetadataReferences(
+ (SourceBuilder previous, EquatableImmutableArray MetadataReferences) data,
+ CancellationToken _)
+ => data.previous with { MetadataReferences = data.MetadataReferences };
+
+ ///
+ /// This returns essentially the same data, but no longer nullable.
+ ///
+ public GeneratorSourceData Build() => new(
+ AttributeContext,
+ Options!.Value,
+ Compilation!.Value,
+ ParseOptions!.Value,
+ AdditionalTexts!,
+ MetadataReferences!);
+}
\ No newline at end of file
diff --git a/SourceGeneratorContext/SourceGeneratorContext.csproj b/SourceGeneratorContext/SourceGeneratorContext.csproj
index f992cbe..27139df 100644
--- a/SourceGeneratorContext/SourceGeneratorContext.csproj
+++ b/SourceGeneratorContext/SourceGeneratorContext.csproj
@@ -51,7 +51,19 @@
+
+ true
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
@@ -61,22 +73,18 @@
-
-
-
-
-
-
-
-
+
+
+
+
diff --git a/SourceGeneratorContext/SourceGeneratorContext.csproj.DotSettings b/SourceGeneratorContext/SourceGeneratorContext.csproj.DotSettings
new file mode 100644
index 0000000..2d05e85
--- /dev/null
+++ b/SourceGeneratorContext/SourceGeneratorContext.csproj.DotSettings
@@ -0,0 +1,2 @@
+
+ True
\ No newline at end of file
diff --git a/SourceGeneratorContext/Templates.cs b/SourceGeneratorContext/Templates.cs
index 3b58285..f38a00d 100644
--- a/SourceGeneratorContext/Templates.cs
+++ b/SourceGeneratorContext/Templates.cs
@@ -1,28 +1,29 @@
-namespace Datacute.SourceGeneratorContext;
+using Datacute.AdditionalTextConstantGenerator;
-internal static class Templates
+namespace Datacute.SourceGeneratorContext;
+
+[AdditionalTextConstants(".cs", "Templates")]
+internal static partial class Templates
{
private const string GeneratorNamespace = "Datacute.SourceGeneratorContext";
private const string AttributeName = "SourceGeneratorContextAttribute";
public const string AttributeFullyQualified = GeneratorNamespace + "." + AttributeName;
- public const string AutoGeneratedComment = /* language=c# */
- @"//------------------------------------------------------------------------------
-//
-// This code was generated by the Datacute.SourceGeneratorContext.
-//
-//------------------------------------------------------------------------------
-";
+ public const string AttributeHintName =
+ "Datacute.SourceGeneratorContext.SourceGeneratorContextAttribute.g.cs";
+
+ public const string IncludeFlagsHintName =
+ "Datacute.SourceGeneratorContext.IncludeFlags.g.cs";
public const string ClassDocCommentsBegin = /* language=c# */
- @"{0}///
-{0}/// When this item is examined by a source generator...
+ @"///
+/// When this item is examined by a source generator...
";
public const string ClassDocCommentsSectionBegin = /* language=c# */
- @"{0}/// {1} contains:
-{0}///
-{0}/// KeyValue
+ @"/// {0} contains:
+///
+/// KeyValue
";
public const string OptionsLine = /* language=c# */
@@ -30,11 +31,11 @@ internal static class Templates
";
public const string ClassDocCommentsSectionEnd = /* language=c# */
- @"{0}///
+ @"///
";
public const string ClassDocCommentsEnd = /* language=c# */
- @"{0}///
+ @"///
";
public static string EscapeStringForDocComments(string input) =>
diff --git a/SourceGeneratorContext/Templates/IncludeFlags.cs b/SourceGeneratorContext/Templates/IncludeFlags.cs
new file mode 100644
index 0000000..e39e41f
--- /dev/null
+++ b/SourceGeneratorContext/Templates/IncludeFlags.cs
@@ -0,0 +1,98 @@
+using System;
+
+namespace Datacute.SourceGeneratorContext
+{
+ ///
+ /// Specifies the types of information to include in the generated source context documentation.
+ ///
+ [Flags]
+ public enum IncludeFlags : uint
+ {
+ ///
+ /// If no other specific flags are set, a basic summary of the context is included.
+ /// This flag is often managed internally by the generator to provide a default output.
+ ///
+ Summary = 0,
+
+ ///
+ /// Includes details about the GeneratorAttributeSyntaxContext.TargetSymbol.
+ ///
+ AttributeContextTargetSymbol = 1U << 0,
+
+ ///
+ /// Includes details about the GeneratorAttributeSyntaxContext.TargetSymbol when cast to an ITypeSymbol.
+ ///
+ AttributeContextTypeSymbol = 1U << 1,
+
+ ///
+ /// Includes details about the GeneratorAttributeSyntaxContext.TargetSymbol when cast to an INamedTypeSymbol.
+ ///
+ AttributeContextNamedTypeSymbol = 1U << 2,
+
+ ///
+ /// Includes details about the GeneratorAttributeSyntaxContext.TargetNode.
+ ///
+ AttributeContextTargetNode = 1U << 3,
+
+ ///
+ /// Includes details about the GeneratorAttributeSyntaxContext.Attributes.
+ ///
+ AttributeContextAttributes = 1U << 4,
+
+ ///
+ /// Includes details about all attributes applied to the target symbol (using GetAttributes()).
+ ///
+ AttributeContextAllAttributes = 1U << 5,
+
+ ///
+ /// Includes details from the AnalyzerConfigOptionsProvider's GlobalOptions.
+ ///
+ GlobalOptions = 1U << 6,
+
+ ///
+ /// Includes general details about the Compilation.
+ ///
+ Compilation = 1U << 7,
+
+ ///
+ /// Includes details about the Compilation's options.
+ ///
+ CompilationOptions = 1U << 8,
+
+ ///
+ /// Includes details about the Compilation's assembly.
+ ///
+ CompilationAssembly = 1U << 9,
+
+ ///
+ /// Includes counts and names of Compilation's references (e.g., References, DirectiveReferences).
+ ///
+ CompilationReferences = 1U << 10,
+
+ ///
+ /// Includes details about the ParseOptionsProvider's ParseOptions.
+ ///
+ ParseOptions = 1U << 11,
+
+ ///
+ /// Includes details about AdditionalTextsProvider's AdditionalText entries.
+ ///
+ AdditionalTexts = 1U << 12,
+
+ ///
+ /// Includes details about AdditionalTextsProvider's AdditionalText options (from AnalyzerConfigOptions).
+ ///
+ AdditionalTextsOptions = 1U << 13,
+
+ ///
+ /// Includes details about MetadataReferencesProvider's MetadataReference entries.
+ ///
+ MetadataReferences = 1U << 14,
+
+ ///
+ /// Includes all available details about the source generation context.
+ ///
+ All = ~0U
+
+ }
+}
diff --git a/SourceGeneratorContext/Templates/SourceGeneratorContextAttribute.cs b/SourceGeneratorContext/Templates/SourceGeneratorContextAttribute.cs
new file mode 100644
index 0000000..4a04ac0
--- /dev/null
+++ b/SourceGeneratorContext/Templates/SourceGeneratorContextAttribute.cs
@@ -0,0 +1,58 @@
+using System;
+// ReSharper disable UnusedAutoPropertyAccessor.Global Properties getters are not used as the source generator reads the source code.
+// ReSharper disable UnusedParameter.Local Unused parameters are used to demonstrate behaviour.
+
+namespace Datacute.SourceGeneratorContext;
+
+///
+/// Add this attribute to a partial class to generate doc-comments detailing the source generation context.
+///
+[System.Diagnostics.Conditional("DATACUTE_SOURCEGENERATORCONTEXTATTRIBUTE_USAGES")]
+[AttributeUsage(
+ validOn: AttributeTargets.Class |
+ AttributeTargets.Interface |
+ AttributeTargets.Struct, // Method and Property should be allowed too
+ Inherited = true, // Inherited to show how SyntaxProvider.ForAttributeWithMetadataName doesn't support inheritance
+ AllowMultiple = true)] // AllowMultiple to show the differences when multiple attributes are applied
+public class SourceGeneratorContextAttribute : Attribute
+{
+ ///
+ /// There is a huge amount of information available, but Visual Studio does not scroll doc-comments.
+ /// So either IncludeAll and view the generated source, or set one of the named parameters to control what gets output:
+ ///
+ /// [SourceGeneratorContext(IncludeFlags.All)]
+ /// internal partial class Example;
+ ///
+ ///
+ public SourceGeneratorContextAttribute(IncludeFlags flags = IncludeFlags.Summary)
+ {
+ IncludeFlags = flags;
+ }
+
+ ///
+ /// Flags to control what information is included in the generated doc-comments.
+ ///
+ public IncludeFlags IncludeFlags { get; set; }
+
+ #region Demonstration purposes only
+
+ ///
+ /// Example of a named parameter.
+ ///
+ public string ExampleNamedParameter { get; set; } =
+ string.Empty; // only used for demonstrating working with Named Parameters
+
+ ///
+ /// Example of an optional parameter.
+ ///
+ ///
+ public
+ SourceGeneratorContextAttribute(
+ string exampleOptionalParameter) // only used for demonstrating working with Constructor Arguments
+ {
+ // The constructor arguments do not need to be assigned to fields or properties
+ // as the source of the supplied values is what is available to the source generator
+ }
+
+ #endregion
+}
\ No newline at end of file
diff --git a/SourceGeneratorContext/TrackingNames.cs b/SourceGeneratorContext/TrackingNames.cs
deleted file mode 100644
index 0512364..0000000
--- a/SourceGeneratorContext/TrackingNames.cs
+++ /dev/null
@@ -1,30 +0,0 @@
-namespace Datacute.SourceGeneratorContext;
-
-public static class TrackingNames
-{
- public const string InitialExtraction = nameof(InitialExtraction);
- public const string Combine = nameof(Combine);
-
- public const int Generator_Initialize = 0;
- public const int AttributeContext_Transform = 1; // too noisy to include
- public const int AnalyzerConfigOptionsDescription_Select = 2;
- public const int CompilationDescription_Select = 3;
- public const int ParseOptionsDescription_Select = 4;
- public const int AdditionalTextDescription_Select = 5;
- public const int MetadataReferenceDescription_Select = 6;
- public const int Generator_Action = 7;
- public const int DiagnosticLog_Written = 8;
-
- public static readonly Dictionary TracingNames = new()
- {
- { Generator_Initialize, nameof(Generator_Initialize) },
- { AttributeContext_Transform, nameof(AttributeContext_Transform) },
- { AnalyzerConfigOptionsDescription_Select, nameof(AnalyzerConfigOptionsDescription_Select) },
- { CompilationDescription_Select, nameof(CompilationDescription_Select) },
- { ParseOptionsDescription_Select, nameof(ParseOptionsDescription_Select) },
- { AdditionalTextDescription_Select, nameof(AdditionalTextDescription_Select) },
- { MetadataReferenceDescription_Select, nameof(MetadataReferenceDescription_Select) },
- { Generator_Action, nameof(Generator_Action) },
- { DiagnosticLog_Written, nameof(DiagnosticLog_Written) },
- };
-}
\ No newline at end of file
diff --git a/SourceGeneratorContextExample/Program.cs b/SourceGeneratorContextExample/Program.cs
index 4c2cd52..1421cc2 100644
--- a/SourceGeneratorContextExample/Program.cs
+++ b/SourceGeneratorContextExample/Program.cs
@@ -21,53 +21,53 @@ public static partial class ClassInGlobalNamespace;
#region All 'include' options
-[SourceGeneratorContext(IncludeAttributeContextTargetSymbol = true)]
+[SourceGeneratorContext(IncludeFlags.AttributeContextTargetSymbol)]
public partial class ViewClassDocsToSeeGeneratorAttributeSyntaxContextTargetSymbol;
-[SourceGeneratorContext(IncludeAttributeContextTypeSymbol = true)]
+[SourceGeneratorContext(IncludeFlags.AttributeContextTypeSymbol)]
public partial class ViewClassDocsToSeeGeneratorAttributeSyntaxContextTypeSymbol;
-[SourceGeneratorContext(IncludeAttributeContextNamedTypeSymbol = true)]
+[SourceGeneratorContext(IncludeFlags.AttributeContextNamedTypeSymbol)]
public partial class ViewClassDocsToSeeGeneratorAttributeSyntaxContextNamedTypeSymbol;
-[SourceGeneratorContext(IncludeAttributeContextTargetNode = true)]
+[SourceGeneratorContext(IncludeFlags.AttributeContextTargetNode)]
public partial class ViewClassDocsToSeeGeneratorAttributeSyntaxContextTargetNode;
-[SourceGeneratorContext(IncludeAttributeContextAttributes = true)]
+[SourceGeneratorContext(IncludeFlags.AttributeContextAttributes)]
public partial class ViewClassDocsToSeeGeneratorAttributeSyntaxContextAttributes;
-[SourceGeneratorContext(IncludeAttributeContextAllAttributes = true)]
+[SourceGeneratorContext(IncludeFlags.AttributeContextAllAttributes)]
public partial class ViewClassDocsToSeeGeneratorAttributeSyntaxContextAllAttributes;
-[SourceGeneratorContext(IncludeGlobalOptions = true)]
+[SourceGeneratorContext(IncludeFlags.GlobalOptions)]
public partial class ViewClassDocsToSeeAnalyzerConfigOptionsProviderGlobalOptions;
-[SourceGeneratorContext(IncludeCompilation = true)]
+[SourceGeneratorContext(IncludeFlags.Compilation)]
public partial class ViewClassDocsToSeeCompilation;
-[SourceGeneratorContext(IncludeCompilationOptions = true)]
+[SourceGeneratorContext(IncludeFlags.CompilationOptions)]
public partial class ViewClassDocsToSeeCompilationOptions;
-[SourceGeneratorContext(IncludeCompilationAssembly = true)]
+[SourceGeneratorContext(IncludeFlags.CompilationAssembly)]
public partial class ViewClassDocsToSeeCompilationAssembly;
-[SourceGeneratorContext(IncludeCompilationReferences = true)]
+[SourceGeneratorContext(IncludeFlags.CompilationReferences)]
public partial class ViewClassDocsToSeeCompilationReferences;
-[SourceGeneratorContext(IncludeParseOptions = true)]
+[SourceGeneratorContext(IncludeFlags.ParseOptions)]
public partial class ViewClassDocsToSeeParseOptions;
-[SourceGeneratorContext(IncludeAdditionalTexts = true)]
+[SourceGeneratorContext(IncludeFlags.AdditionalTexts)]
public partial class ViewClassDocsToSeeAdditionalTexts;
-[SourceGeneratorContext(IncludeMetadataReferences = true)]
+[SourceGeneratorContext(IncludeFlags.MetadataReferences)]
public partial class ViewClassDocsToSeeMetadataReferences;
// IncludeAdditionalTextsOptions seems really repetitive, so is not included in "includeAll"
-[SourceGeneratorContext(IncludeAdditionalTexts = true, IncludeAdditionalTextsOptions = true)]
+[SourceGeneratorContext(IncludeFlags.AdditionalTexts | IncludeFlags.AdditionalTextsOptions)]
public partial class ViewClassDocsToSeeAdditionalTextsWithOptions;
-[SourceGeneratorContext(IncludeAll = true)]
+[SourceGeneratorContext(IncludeFlags.All)]
public partial class ViewClassDocsToSeeAllAvailableDetails;
#endregion
@@ -150,7 +150,7 @@ namespace ExampleNamespace
[SourceGeneratorContext]
internal static partial class ClassInNamespace;
- [SourceGeneratorContext(IncludeAttributeContextTypeSymbol = true)]
+ [SourceGeneratorContext(IncludeFlags.AttributeContextTypeSymbol)]
internal partial record RecordClass(string Example)
{
[SourceGeneratorContext]
@@ -165,7 +165,7 @@ internal static partial class InnerClassWithinParentClass
{
[Obsolete("Included in `TargetSymbol.AllAttributes()`")]
[SourceGeneratorContext("Included in `Attributes` and `TargetSymbol.AllAttributes()`")]
- [SourceGeneratorContext]
+ [SourceGeneratorContext(IncludeFlags.AttributeContextAllAttributes)]
private static partial class InnerClassWithinMultipleParents;
}
@@ -178,10 +178,10 @@ internal partial class InnerClassOfGenericClass;
}
}
-[SourceGeneratorContext(IncludeAttributeContextTypeSymbol = true)]
+[SourceGeneratorContext(IncludeFlags.AttributeContextTypeSymbol)]
public partial struct ExampleStructure;
-[SourceGeneratorContext(IncludeAttributeContextTypeSymbol = true)]
+[SourceGeneratorContext(IncludeFlags.AttributeContextTypeSymbol)]
public partial interface IExampleInterface;
diff --git a/SourceGeneratorContextExample/SourceGeneratorContextExample.csproj b/SourceGeneratorContextExample/SourceGeneratorContextExample.csproj
index 4d54c55..cbecd2c 100644
--- a/SourceGeneratorContextExample/SourceGeneratorContextExample.csproj
+++ b/SourceGeneratorContextExample/SourceGeneratorContextExample.csproj
@@ -30,13 +30,8 @@
-
-
-
-
-
\ No newline at end of file
diff --git a/global.json b/global.json
index f4fd385..a24b744 100644
--- a/global.json
+++ b/global.json
@@ -1,7 +1,6 @@
{
"sdk": {
"version": "9.0.0",
- "rollForward": "latestMajor",
- "allowPrerelease": true
+ "rollForward": "latestFeature"
}
}
\ No newline at end of file
diff --git a/version.props b/version.props
index 356ac8b..71bc521 100644
--- a/version.props
+++ b/version.props
@@ -1,6 +1,14 @@
- 0.0.2
- alpha
+ 1.0.0
+
+
+
+ local
+
+
+
+
+
\ No newline at end of file
diff --git a/versionsuffix.ci.props b/versionsuffix.ci.props
new file mode 100644
index 0000000..0c3f45c
--- /dev/null
+++ b/versionsuffix.ci.props
@@ -0,0 +1,5 @@
+
+
+ alpha.$(GITHUB_RUN_NUMBER)
+
+
\ No newline at end of file
diff --git a/versionsuffix.local.props b/versionsuffix.local.props
new file mode 100644
index 0000000..b4f5215
--- /dev/null
+++ b/versionsuffix.local.props
@@ -0,0 +1,9 @@
+
+
+ dev-$([System.DateTime]::UtcNow.ToString("yyyyMMdd-HHmmss"))
+
+
+
+ dev
+
+
\ No newline at end of file
diff --git a/versionsuffix.release.props b/versionsuffix.release.props
new file mode 100644
index 0000000..759a431
--- /dev/null
+++ b/versionsuffix.release.props
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file