Skip to content

Commit

Permalink
Update generator to really be incremental (#83)
Browse files Browse the repository at this point in the history
  • Loading branch information
k94ll13nn3 authored Oct 15, 2023
1 parent c8fee8b commit b8b1d49
Show file tree
Hide file tree
Showing 30 changed files with 1,160 additions and 260 deletions.
4 changes: 2 additions & 2 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,8 @@ dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggesti
dotnet_style_prefer_inferred_tuple_names = true:suggestion
dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion
dotnet_style_prefer_auto_properties = true:suggestion
dotnet_style_prefer_conditional_expression_over_assignment = true:refactoring
dotnet_style_prefer_conditional_expression_over_return = true:refactoring
dotnet_style_prefer_conditional_expression_over_assignment = true:none
dotnet_style_prefer_conditional_expression_over_return = true:none
csharp_prefer_simple_default_expression = true:suggestion

# Expression-bodied members
Expand Down
4 changes: 3 additions & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
<AnalysisMode>AllEnabledByDefault</AnalysisMode>
<ImplicitUsings>enable</ImplicitUsings>
<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<NoWarn>$(NoWarn);CS1591</NoWarn>
</PropertyGroup>

<ItemGroup>
Expand All @@ -25,7 +27,7 @@

<!-- MinVer properties -->
<PropertyGroup>
<MinVerMinimumMajorMinor>4.0</MinVerMinimumMajorMinor>
<MinVerMinimumMajorMinor>5.0</MinVerMinimumMajorMinor>
<MinVerAutoIncrement>minor</MinVerAutoIncrement>
<MinVerTagPrefix>v</MinVerTagPrefix>
<MinVerDefaultPreReleaseIdentifiers>dev.0</MinVerDefaultPreReleaseIdentifiers>
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ C# source generator that generates a constructor from readonly fields/properties
|---------|---------------|----------|
| <=1.3.0 | 16.10+ | 5.0.300+ |
| >=2.0.0 | 17.0+ | 6.0.100+ |
| >=5.0.0 | 17.6+ | 7.0.302+ |

## Basic usage

Expand Down
2 changes: 1 addition & 1 deletion global.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"sdk": {
"version": "7.0.100",
"version": "7.0.401",
"rollForward": "latestMajor",
"allowPrerelease": false
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
namespace AutoConstructor.Generator.Analyzers;

[DiagnosticAnalyzer(LanguageNames.CSharp)]
public class ClassWithoutFieldsToInjectAnalyzer : DiagnosticAnalyzer
public sealed class ClassWithoutFieldsToInjectAnalyzer : DiagnosticAnalyzer
{
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => ImmutableArray.Create(DiagnosticDescriptors.ClassWithoutFieldsToInjectRule);

Expand All @@ -23,9 +23,9 @@ private static void AnalyzeSymbol(SymbolAnalysisContext context)
{
var symbol = (INamedTypeSymbol)context.Symbol;

if (symbol.GetAttribute(Source.AttributeFullName, context.Compilation) is AttributeData attr)
if (symbol.GetAttribute(Source.AttributeFullName) is AttributeData attr)
{
bool hasFields = SymbolHasFields(context.Compilation, symbol) || ParentHasFields(context.Compilation, symbol);
bool hasFields = SymbolHasFields(symbol) || ParentHasFields(context.Compilation, symbol);
if (!hasFields)
{
SyntaxReference? propertyTypeIdentifier = attr.ApplicationSyntaxReference;
Expand All @@ -39,26 +39,26 @@ private static void AnalyzeSymbol(SymbolAnalysisContext context)
}
}

private static bool SymbolHasFields(Compilation compilation, INamedTypeSymbol symbol)
private static bool SymbolHasFields(INamedTypeSymbol symbol)
{
return symbol.GetMembers()
.OfType<IFieldSymbol>()
.Any(x => x.CanBeInjected(compilation)
.Any(x => x.CanBeInjected()
&& !x.IsStatic
&& x.IsReadOnly
&& !x.IsInitialized()
&& !x.HasAttribute(Source.IgnoreAttributeFullName, compilation));
&& !x.HasAttribute(Source.IgnoreAttributeFullName));
}

private static bool ParentHasFields(Compilation compilation, INamedTypeSymbol symbol)
{
INamedTypeSymbol? baseType = symbol.BaseType;

if (baseType?.BaseType is not null && baseType?.Constructors.Count(d => !d.IsStatic) == 1)
if (baseType?.BaseType is not null && baseType.Constructors.Count(d => !d.IsStatic) == 1)
{
IMethodSymbol constructor = baseType.Constructors.Single(d => !d.IsStatic);
return baseType?.HasAttribute(Source.AttributeFullName, compilation) is true
? SymbolHasFields(compilation, baseType) || ParentHasFields(compilation, baseType)
return baseType.HasAttribute(Source.AttributeFullName)
? SymbolHasFields(baseType) || ParentHasFields(compilation, baseType)
: constructor.Parameters.Length > 0;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
namespace AutoConstructor.Generator.Analyzers;

[DiagnosticAnalyzer(LanguageNames.CSharp)]
public class ClassWithoutPartialAnalyzer : DiagnosticAnalyzer
public sealed class ClassWithoutPartialAnalyzer : DiagnosticAnalyzer
{
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => ImmutableArray.Create(DiagnosticDescriptors.ClassWithoutPartialRule);

Expand All @@ -26,7 +26,7 @@ private static void AnalyzeSymbol(SymbolAnalysisContext context)
var symbol = (INamedTypeSymbol)context.Symbol;

if (symbol.DeclaringSyntaxReferences[0].GetSyntax() is ClassDeclarationSyntax classDeclarationSyntax
&& symbol.HasAttribute(Source.AttributeFullName, context.Compilation)
&& symbol.HasAttribute(Source.AttributeFullName)
&& !classDeclarationSyntax.Modifiers.Any(SyntaxKind.PartialKeyword))
{
var diagnostic = Diagnostic.Create(DiagnosticDescriptors.ClassWithoutPartialRule, classDeclarationSyntax.Identifier.GetLocation());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
namespace AutoConstructor.Generator.Analyzers;

[DiagnosticAnalyzer(LanguageNames.CSharp)]
public class IgnoreAttributeOnNonProcessedFieldAnalyzer : DiagnosticAnalyzer
public sealed class IgnoreAttributeOnNonProcessedFieldAnalyzer : DiagnosticAnalyzer
{
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => ImmutableArray.Create(DiagnosticDescriptors.IgnoreAttributeOnNonProcessedFieldRule);

Expand All @@ -23,8 +23,8 @@ private static void AnalyzeSymbol(SymbolAnalysisContext context)
{
var symbol = (IFieldSymbol)context.Symbol;

if (symbol.GetAttribute(Source.IgnoreAttributeFullName, context.Compilation) is AttributeData attr
&& (!symbol.CanBeInjected(context.Compilation) || symbol.IsStatic || !symbol.IsReadOnly || symbol.IsInitialized()))
if (symbol.GetAttribute(Source.IgnoreAttributeFullName) is AttributeData attr
&& (!symbol.CanBeInjected() || symbol.IsStatic || !symbol.IsReadOnly || symbol.IsInitialized()))
{
SyntaxReference? propertyTypeIdentifier = attr.ApplicationSyntaxReference;
if (propertyTypeIdentifier is not null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
namespace AutoConstructor.Generator.Analyzers;

[DiagnosticAnalyzer(LanguageNames.CSharp)]
public class IgnoreOrInjectAttributeOnClassWithoutAttributeAnalyzer : DiagnosticAnalyzer
public sealed class IgnoreOrInjectAttributeOnClassWithoutAttributeAnalyzer : DiagnosticAnalyzer
{
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => ImmutableArray.Create(DiagnosticDescriptors.IgnoreOrInjectAttributeOnClassWithoutAttributeRule);

Expand All @@ -24,17 +24,16 @@ private static void AnalyzeSymbol(SymbolAnalysisContext context)
var symbol = (INamedTypeSymbol)context.Symbol;

var fields = symbol.GetMembers().OfType<IFieldSymbol>()
.Where(x => x.HasAttribute(Source.IgnoreAttributeFullName, context.Compilation) || x.HasAttribute(Source.InjectAttributeFullName, context.Compilation))
.Where(x => x.HasAttribute(Source.IgnoreAttributeFullName) || x.HasAttribute(Source.InjectAttributeFullName))
.ToList();

if (symbol.GetAttribute(Source.AttributeFullName, context.Compilation) is null
&& fields.Count > 0)
if (symbol.GetAttribute(Source.AttributeFullName) is null && fields.Count > 0)
{
foreach (IFieldSymbol field in fields)
{
foreach (string attributeName in new[] { Source.IgnoreAttributeFullName, Source.InjectAttributeFullName })
{
if (field.GetAttribute(attributeName, context.Compilation) is AttributeData attr)
if (field.GetAttribute(attributeName) is AttributeData attr)
{
SyntaxReference? propertyTypeIdentifier = attr.ApplicationSyntaxReference;
if (propertyTypeIdentifier is not null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
namespace AutoConstructor.Generator.Analyzers;

[DiagnosticAnalyzer(LanguageNames.CSharp)]
public class InjectAttributeOnIgnoredFieldAnalyzer : DiagnosticAnalyzer
public sealed class InjectAttributeOnIgnoredFieldAnalyzer : DiagnosticAnalyzer
{
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => ImmutableArray.Create(DiagnosticDescriptors.InjectAttributeOnIgnoredFieldRule);

Expand All @@ -23,8 +23,8 @@ private static void AnalyzeSymbol(SymbolAnalysisContext context)
{
var symbol = (IFieldSymbol)context.Symbol;

if (symbol.GetAttribute(Source.InjectAttributeFullName, context.Compilation) is AttributeData attr
&& (!symbol.CanBeInjected(context.Compilation) || symbol.IsStatic || !symbol.IsReadOnly || symbol.IsInitialized() || symbol.HasAttribute(Source.IgnoreAttributeFullName, context.Compilation)))
if (symbol.GetAttribute(Source.InjectAttributeFullName) is AttributeData attr
&& (!symbol.CanBeInjected() || symbol.IsStatic || !symbol.IsReadOnly || symbol.IsInitialized() || symbol.HasAttribute(Source.IgnoreAttributeFullName)))
{
SyntaxReference? propertyTypeIdentifier = attr.ApplicationSyntaxReference;
if (propertyTypeIdentifier is not null)
Expand Down
10 changes: 7 additions & 3 deletions src/AutoConstructor.Generator/AutoConstructor.Generator.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@

<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<GenerateDocumentationFile>false</GenerateDocumentationFile>
<IncludeBuildOutput>false</IncludeBuildOutput> <!-- Do not include the generator as a lib dependency -->
<SuppressDependenciesWhenPacking>true</SuppressDependenciesWhenPacking>
<DevelopmentDependency>true</DevelopmentDependency>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<IsRoslynComponent>true</IsRoslynComponent>
<EnablePackageValidation>true</EnablePackageValidation>
<EnforceExtendedAnalyzerRules>true</EnforceExtendedAnalyzerRules>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>

<PropertyGroup>
Expand Down Expand Up @@ -37,9 +37,13 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="[4.0.1]" PrivateAssets="all" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="[4.6.0]" PrivateAssets="all" />
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.4" PrivateAssets="all" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="[4.0.1]" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="[4.6.0]" />
<PackageReference Include="PolySharp" Version="1.13.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>

<ItemGroup>
Expand Down
Loading

0 comments on commit b8b1d49

Please sign in to comment.