Skip to content

Commit aafbbb6

Browse files
authored
Merge pull request #25 from bramerdaniel/develop
Feature/diagnostic analyzer
2 parents 8eea550 + 9418c45 commit aafbbb6

17 files changed

Lines changed: 460 additions & 24 deletions

.github/workflows/buildAndTest.yml

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ jobs:
5858
uses: actions/upload-artifact@v3.0.0
5959
with:
6060
name: binaries
61-
path: ${{ env.SOLUTION_DIRECTORY }}\Release\net6.0\*
61+
path: ${{ env.SOLUTION_DIRECTORY }}\Release\net48\*
6262
retention-days: 1
6363

6464

@@ -89,12 +89,6 @@ jobs:
8989
- name: checkout branch
9090
uses: actions/checkout@v3
9191

92-
#- name: download artifacts
93-
# uses: actions/download-artifact@v3.0.0
94-
# with:
95-
# name: nugetPackage
96-
# path: src\FluentSetups.IntegrationTests\packages
97-
9892
# the output directory of the FluentSetup project,
9993
# this makes it possible to use that also for local usage
10094
- name: download artifacts

src/Directory.Build.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<Project>
22
<PropertyGroup>
3-
<FluentSetupsPackageVersion>0.3.1</FluentSetupsPackageVersion>
3+
<FluentSetupsPackageVersion>0.3.2</FluentSetupsPackageVersion>
44
<SignAssembly>True</SignAssembly>
55
<AssemblyOriginatorKeyFile>..\..\certificate\FluentSetups.snk</AssemblyOriginatorKeyFile>
66
</PropertyGroup>

src/Directory.Build.targets

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,6 @@
1212

1313
<PackageReference Update="Microsoft.CodeAnalysis.Analyzers" Version="3.3.3"/>
1414
<PackageReference Update="Microsoft.CodeAnalysis.CSharp" Version="4.2.0" />
15+
<PackageReference Update="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="4.2.0" />
1516
</ItemGroup>
1617
</Project>
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
# To learn more about .editorconfig see https://aka.ms/editorconfigdocs
2+
###############################
3+
# Core EditorConfig Options #
4+
###############################
5+
root = true
6+
# All files
7+
[*]
8+
indent_style = space
9+
10+
# XML project files
11+
[*.{csproj,vbproj,vcxproj,vcxproj.filters,proj,projitems,shproj}]
12+
indent_size = 2
13+
14+
# XML config files
15+
[*.{props,targets,ruleset,config,nuspec,resx,vsixmanifest,vsct}]
16+
indent_size = 2
17+
18+
# Code files
19+
[*.{cs,csx,vb,vbx}]
20+
indent_size = 4
21+
insert_final_newline = true
22+
charset = utf-8-bom
23+
###############################
24+
# .NET Coding Conventions #
25+
###############################
26+
[*.{cs,vb}]
27+
# Organize usings
28+
dotnet_sort_system_directives_first = true
29+
# this. preferences
30+
dotnet_style_qualification_for_field = false:silent
31+
dotnet_style_qualification_for_property = false:silent
32+
dotnet_style_qualification_for_method = false:silent
33+
dotnet_style_qualification_for_event = false:silent
34+
# Language keywords vs BCL types preferences
35+
dotnet_style_predefined_type_for_locals_parameters_members = true:silent
36+
dotnet_style_predefined_type_for_member_access = true:silent
37+
# Parentheses preferences
38+
dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:silent
39+
dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:silent
40+
dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:silent
41+
dotnet_style_parentheses_in_other_operators = never_if_unnecessary:silent
42+
# Modifier preferences
43+
dotnet_style_require_accessibility_modifiers = for_non_interface_members:silent
44+
dotnet_style_readonly_field = true:suggestion
45+
# Expression-level preferences
46+
dotnet_style_object_initializer = true:suggestion
47+
dotnet_style_collection_initializer = true:suggestion
48+
dotnet_style_explicit_tuple_names = true:suggestion
49+
dotnet_style_null_propagation = true:suggestion
50+
dotnet_style_coalesce_expression = true:suggestion
51+
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:silent
52+
dotnet_style_prefer_inferred_tuple_names = true:suggestion
53+
dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion
54+
dotnet_style_prefer_auto_properties = true:silent
55+
dotnet_style_prefer_conditional_expression_over_assignment = true:silent
56+
dotnet_style_prefer_conditional_expression_over_return = true:silent
57+
###############################
58+
# Naming Conventions #
59+
###############################
60+
# Style Definitions
61+
dotnet_naming_style.pascal_case_style.capitalization = pascal_case
62+
# Use PascalCase for constant fields
63+
dotnet_naming_rule.constant_fields_should_be_pascal_case.severity = suggestion
64+
dotnet_naming_rule.constant_fields_should_be_pascal_case.symbols = constant_fields
65+
dotnet_naming_rule.constant_fields_should_be_pascal_case.style = pascal_case_style
66+
dotnet_naming_symbols.constant_fields.applicable_kinds = field
67+
dotnet_naming_symbols.constant_fields.applicable_accessibilities = *
68+
dotnet_naming_symbols.constant_fields.required_modifiers = const
69+
dotnet_style_operator_placement_when_wrapping = beginning_of_line
70+
tab_width = 3
71+
end_of_line = crlf
72+
###############################
73+
# C# Coding Conventions #
74+
###############################
75+
[*.cs]
76+
# var preferences
77+
csharp_style_var_for_built_in_types = true:silent
78+
csharp_style_var_when_type_is_apparent = true:silent
79+
csharp_style_var_elsewhere = true:silent
80+
# Expression-bodied members
81+
csharp_style_expression_bodied_methods = false:silent
82+
csharp_style_expression_bodied_constructors = false:silent
83+
csharp_style_expression_bodied_operators = false:silent
84+
csharp_style_expression_bodied_properties = true:silent
85+
csharp_style_expression_bodied_indexers = true:silent
86+
csharp_style_expression_bodied_accessors = true:silent
87+
# Pattern matching preferences
88+
csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion
89+
csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
90+
# Null-checking preferences
91+
csharp_style_throw_expression = true:suggestion
92+
csharp_style_conditional_delegate_call = true:suggestion
93+
# Modifier preferences
94+
csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:suggestion
95+
# Expression-level preferences
96+
csharp_prefer_braces = true:silent
97+
csharp_style_deconstructed_variable_declaration = true:suggestion
98+
csharp_prefer_simple_default_expression = true:suggestion
99+
csharp_style_pattern_local_over_anonymous_function = true:suggestion
100+
csharp_style_inlined_variable_declaration = true:suggestion
101+
###############################
102+
# C# Formatting Rules #
103+
###############################
104+
# New line preferences
105+
csharp_new_line_before_open_brace = all
106+
csharp_new_line_before_else = true
107+
csharp_new_line_before_catch = true
108+
csharp_new_line_before_finally = true
109+
csharp_new_line_before_members_in_object_initializers = true
110+
csharp_new_line_before_members_in_anonymous_types = true
111+
csharp_new_line_between_query_expression_clauses = true
112+
# Indentation preferences
113+
csharp_indent_case_contents = true
114+
csharp_indent_switch_labels = true
115+
csharp_indent_labels = flush_left
116+
# Space preferences
117+
csharp_space_after_cast = false
118+
csharp_space_after_keywords_in_control_flow_statements = true
119+
csharp_space_between_method_call_parameter_list_parentheses = false
120+
csharp_space_between_method_declaration_parameter_list_parentheses = false
121+
csharp_space_between_parentheses = false
122+
csharp_space_before_colon_in_inheritance_clause = true
123+
csharp_space_after_colon_in_inheritance_clause = true
124+
csharp_space_around_binary_operators = before_and_after
125+
csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
126+
csharp_space_between_method_call_name_and_opening_parenthesis = false
127+
csharp_space_between_method_call_empty_parameter_list_parentheses = false
128+
# Wrapping preferences
129+
csharp_preserve_single_line_statements = true
130+
csharp_preserve_single_line_blocks = true
131+
csharp_using_directive_placement = outside_namespace:silent
132+
csharp_prefer_simple_using_statement = true:suggestion
133+
csharp_style_namespace_declarations = block_scoped:silent
134+
csharp_style_prefer_method_group_conversion = true:silent
135+
csharp_style_expression_bodied_lambdas = true:silent
136+
csharp_style_expression_bodied_local_functions = false:silent
137+
138+
# Default severity for analyzer diagnostics with category 'FluentSetups'
139+
# dotnet_analyzer_diagnostic.category-FluentSetups.severity = suggestion
140+
dotnet_diagnostic.FSI0001.severity = warning
141+
142+
143+
144+

src/FluentSetups.IntegrationTests/FluentSetups.IntegrationTests.csproj

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,12 @@
1616
<PackageReference Include="FluentSetups" />
1717
</ItemGroup>
1818

19+
<ItemGroup>
20+
<EditorConfigFiles Remove="C:\Users\bramerd\source\repos\FluentSetups\src\FluentSetups.IntegrationTests\.editorconfig" />
21+
</ItemGroup>
22+
23+
<ItemGroup>
24+
<None Include="C:\Users\bramerd\source\repos\FluentSetups\src\FluentSetups.IntegrationTests\.editorconfig" />
25+
</ItemGroup>
26+
1927
</Project>

src/FluentSetups.IntegrationTests/Setups/MultiplePartialMembers.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,5 @@ public partial class MultiplePartialMembers
1414
}
1515

1616
public partial class MultiplePartialMembers
17-
{
18-
}
17+
{
18+
}
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
// --------------------------------------------------------------------------------------------------------------------
2+
// <copyright file="MultiplePartialSetupMembersAnalyzer.cs" company="KUKA Deutschland GmbH">
3+
// Copyright (c) KUKA Deutschland GmbH 2006 - 2022
4+
// </copyright>
5+
// --------------------------------------------------------------------------------------------------------------------
6+
7+
namespace FluentSetups.SourceGenerator.Analyzers
8+
{
9+
using System;
10+
using System.Collections.Immutable;
11+
using System.Linq;
12+
13+
using Microsoft.CodeAnalysis;
14+
using Microsoft.CodeAnalysis.Diagnostics;
15+
16+
[DiagnosticAnalyzer(LanguageNames.CSharp)]
17+
public class MultiplePartialSetupMembersAnalyzer : DiagnosticAnalyzer
18+
{
19+
20+
#region Public Properties
21+
22+
/// <summary>Returns a set of descriptors for the diagnostics that this analyzer is capable of producing.</summary>
23+
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics { get; } = ImmutableArray.Create(FluentSetupDiagnostics.MultiplePartialParts);
24+
25+
#endregion
26+
27+
#region Public Methods and Operators
28+
29+
public override void Initialize(AnalysisContext context)
30+
{
31+
context.EnableConcurrentExecution();
32+
33+
context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);
34+
context.RegisterCompilationStartAction(compilationContext =>
35+
{
36+
// We only care about compilations where attribute type "FluentSetup" is available.
37+
var fluentSetupAttribute = compilationContext.Compilation.GetTypeByMetadataName(FluentGeneratorContext.FluentSetupAttributeName);
38+
if (fluentSetupAttribute == null)
39+
{
40+
return;
41+
}
42+
43+
// Register an action that accesses the immutable state and reports diagnostics.
44+
compilationContext.RegisterSymbolAction(symbolContext => AnalyzeSymbol(symbolContext, fluentSetupAttribute), SymbolKind.NamedType);
45+
});
46+
}
47+
48+
#endregion
49+
50+
#region Methods
51+
52+
private static bool IsGeneratedPartialPart(INamedTypeSymbol namedTypeSymbol)
53+
{
54+
foreach (var reference in namedTypeSymbol.DeclaringSyntaxReferences)
55+
{
56+
if (reference.SyntaxTree.FilePath.EndsWith(".generated.cs", StringComparison.InvariantCultureIgnoreCase))
57+
return true;
58+
}
59+
60+
return false;
61+
}
62+
63+
64+
65+
66+
67+
private void AnalyzeSymbol(SymbolAnalysisContext context, INamedTypeSymbol fluentSetupAttribute)
68+
{
69+
var namedTypeSymbol = (INamedTypeSymbol)context.Symbol;
70+
71+
if (namedTypeSymbol.DeclaringSyntaxReferences.Length > 1)
72+
{
73+
var attributeData = namedTypeSymbol.GetAttributes().FirstOrDefault(IsFluentSetupAttribute);
74+
if (attributeData == null || attributeData.AttributeClass == null)
75+
return;
76+
77+
if (IsGeneratedPartialPart(namedTypeSymbol))
78+
return;
79+
80+
var reference = attributeData.ApplicationSyntaxReference;
81+
if (reference == null)
82+
return;
83+
84+
var diagnostic = Diagnostic.Create(FluentSetupDiagnostics.MultiplePartialParts, Location.Create(reference.SyntaxTree, reference.Span), namedTypeSymbol.Name);
85+
context.ReportDiagnostic(diagnostic);
86+
}
87+
88+
bool IsFluentSetupAttribute(AttributeData attributeData)
89+
{
90+
if (fluentSetupAttribute.Equals(attributeData.AttributeClass, SymbolEqualityComparer.Default))
91+
return true;
92+
return false;
93+
}
94+
}
95+
96+
#endregion
97+
}
98+
}

src/FluentSetups.SourceGenerator/FluentGeneratorContext.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ public bool TryGetMissingType(out string missingType)
9797

9898
#region Methods
9999

100-
private bool IsFluentSetupAttribute(AttributeData attributeData)
100+
internal bool IsFluentSetupAttribute(AttributeData attributeData)
101101
{
102102
if (FluentSetupAttribute.Equals(attributeData.AttributeClass, SymbolEqualityComparer.Default))
103103
return true;

src/FluentSetups.SourceGenerator/FluentModelGenerator.cs

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ namespace FluentSetups.SourceGenerator
88
{
99
using System;
1010
using System.Collections.Generic;
11+
using System.Diagnostics;
1112
using System.Linq;
1213
using System.Text;
1314

@@ -46,14 +47,8 @@ private static void ReportUnknownError(GeneratedSource source, Exception e)
4647

4748
private static void ReportIgnore(GeneratedSource source, FClass ignoredClass)
4849
{
49-
var missingReference = new DiagnosticDescriptor(id: "FSI0001", title: "FluentSetups source generator",
50-
messageFormat: "Fluent setup generation for class {0} is skipped du tue multiple partial members.",
51-
category: nameof(FluentSetupSourceGenerator),
52-
defaultSeverity: DiagnosticSeverity.Info,
53-
isEnabledByDefault: true);
54-
55-
var location = CreateLocation(ignoredClass);
56-
source.AddDiagnostic(Diagnostic.Create(missingReference, location, ignoredClass.ClassName));
50+
////var location = CreateLocation(ignoredClass);
51+
////source.AddDiagnostic(Diagnostic.Create(FluentSetupDiagnostics.MultiplePartialParts, location, ignoredClass.ClassName));
5752
}
5853

5954
private static Location CreateLocation(FClass ignoredClass)
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// --------------------------------------------------------------------------------------------------------------------
2+
// <copyright file="FluentSetupDiagnostics.cs" company="KUKA Deutschland GmbH">
3+
// Copyright (c) KUKA Deutschland GmbH 2006 - 2022
4+
// </copyright>
5+
// --------------------------------------------------------------------------------------------------------------------
6+
7+
namespace FluentSetups.SourceGenerator
8+
{
9+
using System.Diagnostics.CodeAnalysis;
10+
11+
using Microsoft.CodeAnalysis;
12+
13+
[SuppressMessage("MicrosoftCodeAnalysisReleaseTracking", "RS2008:Enable analyzer release tracking")]
14+
public static class FluentSetupDiagnostics
15+
{
16+
internal static readonly DiagnosticDescriptor MultiplePartialParts = new DiagnosticDescriptor(id: "FSI0001",
17+
title: "FluentSetups source generator",
18+
messageFormat: "Fluent setup generation for class '{0}' is skipped du tue multiple partial members",
19+
category: "FluentSetups",
20+
defaultSeverity: DiagnosticSeverity.Info,
21+
isEnabledByDefault: true);
22+
}
23+
}

0 commit comments

Comments
 (0)