Skip to content

Commit 21fcc3a

Browse files
committed
Lift restriction TTRESG052 (Types are now allowed inside generic types)
1 parent 801f979 commit 21fcc3a

File tree

108 files changed

+5897
-970
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

108 files changed

+5897
-970
lines changed

docs

Submodule docs updated from 831547b to 2294ccd

src/Thinktecture.Runtime.Extensions.Analyzers/CodeAnalysis/Diagnostics/ThinktectureRuntimeExtensionsAnalyzer.cs

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@ public sealed class ThinktectureRuntimeExtensionsAnalyzer : DiagnosticAnalyzer
4242
DiagnosticsDescriptors.ExplicitEqualityComparerWithoutComparer,
4343
DiagnosticsDescriptors.MethodWithUseDelegateFromConstructorMustBePartial,
4444
DiagnosticsDescriptors.MethodWithUseDelegateFromConstructorMustNotHaveGenerics,
45-
DiagnosticsDescriptors.TypeMustNotBeInsideGenericType,
4645
DiagnosticsDescriptors.UnionDerivedTypesMustNotBeGeneric,
4746
DiagnosticsDescriptors.UnionMustBeSealedOrHavePrivateConstructorsOnly,
4847
DiagnosticsDescriptors.UnionRecordMustBeSealed,
@@ -798,7 +797,6 @@ private static void ValidateCustomKeyMemberImplementation(
798797

799798
CheckConstructors(context, type, mustBePrivate: false, canHavePrimaryConstructor: false);
800799
TypeMustBePartial(context, type);
801-
TypeMustNotBeInsideGenericType(context, type, tdsLocation);
802800

803801
var assignableMembers = type.GetAssignableFieldsAndPropertiesAndCheckForReadOnly(factory, false, true, context.CancellationToken, context)
804802
.Where(m => !m.IsStatic)
@@ -1052,7 +1050,6 @@ private static void ValidateSmartEnum(
10521050

10531051
CheckConstructors(context, enumType, mustBePrivate: true, canHavePrimaryConstructor: false);
10541052
TypeMustBePartial(context, enumType);
1055-
TypeMustNotBeInsideGenericType(context, enumType, tdsLocation);
10561053

10571054
var items = enumType.GetEnumItems();
10581055

@@ -1114,12 +1111,6 @@ private static void TypeMustNotBeGeneric(SymbolAnalysisContext context, INamedTy
11141111
}
11151112
}
11161113

1117-
private static void TypeMustNotBeInsideGenericType(SymbolAnalysisContext context, INamedTypeSymbol type, Location tdsLocation)
1118-
{
1119-
if (type.IsNestedInGenericClass())
1120-
ReportDiagnostic(context, DiagnosticsDescriptors.TypeMustNotBeInsideGenericType, tdsLocation, BuildTypeName(type));
1121-
}
1122-
11231114
private static void Check_ItemLike_StaticProperties(
11241115
SymbolAnalysisContext context,
11251116
INamedTypeSymbol enumType)

src/Thinktecture.Runtime.Extensions.Refactorings/CodeAnalysis/Refactorings/SwitchMapCompletionRefactoringProvider.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -397,7 +397,7 @@ private static SeparatedSyntaxList<ParameterSyntax> BuildMultipleParameters(int
397397
.WithTrailingTrivia(SyntaxFactory.Space);
398398
}
399399

400-
var name = i == 0 ? "state" : "x";
400+
var name = i == 0 ? Constants.Parameters.STATE : "x";
401401
nodesAndTokens[i * 2] = SyntaxFactory.Parameter(SyntaxFactory.Identifier(name));
402402
}
403403

src/Thinktecture.Runtime.Extensions.Roslyn.Sources/AnalyzerReleases.Unshipped.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,9 @@
22

33
Rule ID | Category | Severity | Notes
44
---------|----------|----------|-------
5+
6+
### Removed Rules
7+
8+
Rule ID | Category | Severity | Notes
9+
---------|----------|----------|-------
10+
TTRESG052 | Thinktecture.Runtime.Extensions | Error | Types are now allowed inside generic types

src/Thinktecture.Runtime.Extensions.Roslyn.Sources/CodeAnalysis/DiagnosticsDescriptors.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ internal static class DiagnosticsDescriptors
2828
public static readonly DiagnosticDescriptor ComplexValueObjectWithStringMembersNeedsDefaultEqualityComparer = new("TTRESG049", "Complex Value Object with string members needs equality comparer", "Complex Value Object with string members needs equality comparer. Use 'DefaultStringComparison' to define the comparer. Example: [ComplexValueObject(DefaultStringComparison = StringComparison.OrdinalIgnoreCase)].", Constants.ANALYZER_CATEGORY, DiagnosticSeverity.Warning, true);
2929
public static readonly DiagnosticDescriptor MethodWithUseDelegateFromConstructorMustBePartial = new("TTRESG050", $"Method with '{Constants.Attributes.UseDelegateFromConstructor.NAME}' must be partial", $"The method '{{0}}' with '{Constants.Attributes.UseDelegateFromConstructor.NAME}' must be marked as partial", Constants.ANALYZER_CATEGORY, DiagnosticSeverity.Error, true);
3030
public static readonly DiagnosticDescriptor MethodWithUseDelegateFromConstructorMustNotHaveGenerics = new("TTRESG051", $"Method with '{Constants.Attributes.UseDelegateFromConstructor.NAME}' must not have generics", $"The method '{{0}}' with '{Constants.Attributes.UseDelegateFromConstructor.NAME}' must not have generic type parameters. Use inheritance approach instead.", Constants.ANALYZER_CATEGORY, DiagnosticSeverity.Error, true);
31-
public static readonly DiagnosticDescriptor TypeMustNotBeInsideGenericType = new("TTRESG052", "The type must not be inside generic type", "Type '{0}' must not be inside a generic type", Constants.ANALYZER_CATEGORY, DiagnosticSeverity.Error, true);
3231
public static readonly DiagnosticDescriptor UnionDerivedTypesMustNotBeGeneric = new("TTRESG053", "Derived type of a union must not be generic", "Derived type '{0}' of a union must not be generic", Constants.ANALYZER_CATEGORY, DiagnosticSeverity.Error, true);
3332
public static readonly DiagnosticDescriptor UnionMustBeSealedOrHavePrivateConstructorsOnly = new("TTRESG054", "Discriminated union must be sealed or have private constructors only", "Discriminated union '{0}' must be sealed or have private constructors only", Constants.ANALYZER_CATEGORY, DiagnosticSeverity.Error, true);
3433
public static readonly DiagnosticDescriptor UnionRecordMustBeSealed = new("TTRESG055", "Discriminated union implemented using a record must be sealed", "Discriminated union '{0}' using a record must be sealed. Use a class for nesting unions.", Constants.ANALYZER_CATEGORY, DiagnosticSeverity.Error, true);

src/Thinktecture.Runtime.Extensions.Roslyn.Sources/Extensions/NamedTypeSymbolExtensions.cs

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -106,21 +106,6 @@ public static ImmutableArray<ContainingTypeState> GetContainingTypes(
106106
return types.DrainToImmutable();
107107
}
108108

109-
public static bool IsNestedInGenericClass(this INamedTypeSymbol type)
110-
{
111-
var containingType = type.ContainingType;
112-
113-
while (containingType is not null)
114-
{
115-
if (containingType.Arity > 0)
116-
return true;
117-
118-
containingType = containingType.ContainingType;
119-
}
120-
121-
return false;
122-
}
123-
124109
public static bool HasLowerAccessibility(
125110
this INamedTypeSymbol type,
126111
Accessibility accessibility,

src/Thinktecture.Runtime.Extensions.SourceGenerator/CodeAnalysis/KeyedJsonCodeGenerator.cs

Lines changed: 18 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ namespace ").Append(_state.Namespace).Append(@";
4343

4444
_sb.RenderContainingTypesStart(_state.ContainingTypes);
4545

46-
var hasGenerics = !_state.GenericParameters.IsDefaultOrEmpty;
46+
var hasGenerics = !_state.GenericParameters.IsDefaultOrEmpty || _state.ContainingTypes.Any(ct => !ct.GenericParameters.IsDefaultOrEmpty);
4747

4848
if (hasGenerics)
4949
{
@@ -93,14 +93,11 @@ private void GenerateFactory(string keyType, bool isString)
9393
public override bool CanConvert(global::System.Type typeToConvert)
9494
{");
9595

96-
if (!_state.GenericParameters.IsDefaultOrEmpty)
97-
{
98-
_sb.Append(@"
96+
_sb.Append(@"
9997
if (!typeToConvert.IsGenericType || typeToConvert.IsGenericTypeDefinition)
10098
return false;
10199
102100
return typeof(").AppendTypeFullyQualifiedWithoutGenerics(_state, _state.ContainingTypes).AppendGenericTypeParameters(_state, constructOpenGeneric: true).Append(") == typeToConvert.GetGenericTypeDefinition();");
103-
}
104101

105102
_sb.Append(@"
106103
}
@@ -114,39 +111,36 @@ public override bool CanConvert(global::System.Type typeToConvert)
114111
throw new global::System.ArgumentNullException(nameof(options));
115112
");
116113

117-
if (!_state.GenericParameters.IsDefaultOrEmpty)
114+
if (_state.UseSpanBasedJsonConverter)
118115
{
119-
if (_state.UseSpanBasedJsonConverter)
120-
{
121-
_sb.Append(@"
116+
_sb.Append(@"
122117
#if NET9_0_OR_GREATER
123118
var converterType = typeof(global::Thinktecture.Text.Json.Serialization.ThinktectureSpanParsableJsonConverter<,>).MakeGenericType(typeToConvert, typeof(").AppendTypeFullyQualified(_state.AttributeInfo.ValidationError).Append(@"));
124119
#else
125120
var converterType = typeof(global::Thinktecture.Text.Json.Serialization.ThinktectureJsonConverter<,>).MakeGenericType(typeToConvert, typeof(").AppendTypeFullyQualified(_state.AttributeInfo.ValidationError).Append(@"));
126121
#endif");
122+
}
123+
else
124+
{
125+
_sb.Append(@"
126+
var converterType = typeof(global::Thinktecture.Text.Json.Serialization.");
127+
128+
if (isString)
129+
{
130+
_sb.Append("ThinktectureJsonConverter<,>).MakeGenericType(typeToConvert, typeof(").AppendTypeFullyQualified(_state.AttributeInfo.ValidationError).Append("))");
127131
}
128132
else
129133
{
130-
_sb.Append(@"
131-
var converterType = typeof(global::Thinktecture.Text.Json.Serialization.");
132-
133-
if (isString)
134-
{
135-
_sb.Append("ThinktectureJsonConverter<,>).MakeGenericType(typeToConvert, typeof(").AppendTypeFullyQualified(_state.AttributeInfo.ValidationError).Append("))");
136-
}
137-
else
138-
{
139-
_sb.Append("ThinktectureJsonConverter<,,>).MakeGenericType(typeToConvert, typeof(").Append(keyType).Append("), typeof(").AppendTypeFullyQualified(_state.AttributeInfo.ValidationError).Append("))");
140-
}
141-
142-
_sb.Append(";");
134+
_sb.Append("ThinktectureJsonConverter<,,>).MakeGenericType(typeToConvert, typeof(").Append(keyType).Append("), typeof(").AppendTypeFullyQualified(_state.AttributeInfo.ValidationError).Append("))");
143135
}
144136

145-
_sb.Append(@"
137+
_sb.Append(";");
138+
}
139+
140+
_sb.Append(@"
146141
147142
return (global::System.Text.Json.Serialization.JsonConverter?)global::System.Activator.CreateInstance(converterType, options)
148143
?? throw new global::System.Exception($""Could not create an instance of json converter of type \""{converterType.FullName}\""."");");
149-
}
150144

151145
_sb.Append(@"
152146
}

src/Thinktecture.Runtime.Extensions.SourceGenerator/CodeAnalysis/KeyedMessagePackCodeGenerator.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ namespace ").Append(_state.Namespace).Append(@";
3838

3939
_sb.RenderContainingTypesStart(_state.ContainingTypes);
4040

41-
var hasGenerics = !_state.GenericParameters.IsDefaultOrEmpty;
41+
var hasGenerics = !_state.GenericParameters.IsDefaultOrEmpty || _state.ContainingTypes.Any(ct => !ct.GenericParameters.IsDefaultOrEmpty);
4242

4343
_sb.Append(@"
4444
[global::MessagePack.MessagePackFormatter(typeof(");

src/Thinktecture.Runtime.Extensions.SourceGenerator/CodeAnalysis/KeyedNewtonsoftJsonCodeGenerator.cs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ namespace ").Append(_state.Namespace).Append(@";
3838

3939
_sb.RenderContainingTypesStart(_state.ContainingTypes);
4040

41-
var hasGenerics = !_state.GenericParameters.IsDefaultOrEmpty;
41+
var hasGenerics = !_state.GenericParameters.IsDefaultOrEmpty || _state.ContainingTypes.Any(ct => !ct.GenericParameters.IsDefaultOrEmpty);
4242

4343
_sb.Append(@"
4444
[global::Newtonsoft.Json.JsonConverterAttribute(typeof(");
@@ -81,14 +81,11 @@ public override bool CanConvert(global::System.Type objectType)
8181
objectType = global::System.Nullable.GetUnderlyingType(objectType) ?? objectType;
8282
");
8383

84-
if (!_state.GenericParameters.IsDefaultOrEmpty)
85-
{
86-
_sb.Append(@"
84+
_sb.Append(@"
8785
if (!objectType.IsGenericType || objectType.IsGenericTypeDefinition)
8886
return false;
8987
9088
return typeof(").AppendTypeFullyQualifiedWithoutGenerics(_state, _state.ContainingTypes).AppendGenericTypeParameters(_state, constructOpenGeneric: true).Append(@") == objectType.GetGenericTypeDefinition();");
91-
}
9289

9390
_sb.Append(@"
9491
}

src/Thinktecture.Runtime.Extensions.SourceGenerator/CodeAnalysis/SmartEnums/SmartEnumCodeGenerator.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ namespace ").Append(_state.Namespace).Append(@"
4848

4949
private void GenerateEnum(CancellationToken cancellationToken)
5050
{
51-
var isGeneric = !_state.GenericParameters.IsDefaultOrEmpty;
51+
var isGeneric = !_state.GenericParameters.IsDefaultOrEmpty || _state.ContainingTypes.Any(ct => !ct.GenericParameters.IsDefaultOrEmpty);
5252

5353
if (_state.KeyMember is not null && !isGeneric)
5454
{

0 commit comments

Comments
 (0)