Skip to content

Commit 599bd74

Browse files
SleepWellPupperPaul Braetz
andauthored
Fix type arrays (#149)
* remove rewriter remainder * fix type arrays --------- Co-authored-by: Paul Braetz <[email protected]>
1 parent 9544ec3 commit 599bd74

File tree

6 files changed

+130
-81
lines changed

6 files changed

+130
-81
lines changed
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// SPDX-License-Identifier: MPL-2.0
2+
3+
namespace RhoMicro.CodeAnalysis.Tests.E2E;
4+
5+
[GenerateFactory]
6+
partial class TestAttribute
7+
{
8+
public Type[] TypeArrayProperty { get; set; } = [];
9+
public Type?[] NullableTypeArrayProperty { get; set; } = [];
10+
public Type[]? TypeNullableArrayProperty { get; set; } = [];
11+
public Type?[]? NullableTypeNullableArrayProperty { get; set; } = [];
12+
}
Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,28 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22

3-
<PropertyGroup>
4-
<TargetFramework>net9.0</TargetFramework>
5-
<ImplicitUsings>enable</ImplicitUsings>
6-
<Nullable>enable</Nullable>
7-
<IsPackable>false</IsPackable>
8-
<RootNamespace>RhoMicro.CodeAnalysis.Tests.E2E</RootNamespace>
9-
</PropertyGroup>
3+
<PropertyGroup>
4+
<TargetFramework>net9.0</TargetFramework>
5+
<ImplicitUsings>enable</ImplicitUsings>
6+
<Nullable>enable</Nullable>
7+
<IsPackable>false</IsPackable>
8+
<RootNamespace>RhoMicro.CodeAnalysis.Tests.E2E</RootNamespace>
9+
</PropertyGroup>
1010

11-
<ItemGroup>
12-
<PackageReference Include="coverlet.collector" Version="6.0.2" />
13-
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.12.0" />
14-
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.11.1" />
15-
<PackageReference Include="xunit" Version="2.9.2" />
16-
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.2" />
17-
<PackageReference Include="DiffPlex" Version="1.7.2" />
18-
</ItemGroup>
11+
<ItemGroup>
12+
<PackageReference Include="coverlet.collector" Version="6.0.2"/>
13+
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.12.0"/>
14+
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.11.1"/>
15+
<PackageReference Include="xunit" Version="2.9.2"/>
16+
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.2"/>
17+
<PackageReference Include="DiffPlex" Version="1.7.2"/>
18+
</ItemGroup>
1919

20-
<ItemGroup>
21-
<ProjectReference Include="../UtilityGenerators/UtilityGenerators.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
22-
</ItemGroup>
20+
<ItemGroup>
21+
<ProjectReference Include="../UtilityGenerators/UtilityGenerators.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false"/>
22+
</ItemGroup>
2323

24-
<ItemGroup>
25-
<Using Include="Xunit" />
26-
</ItemGroup>
24+
<ItemGroup>
25+
<Using Include="Xunit"/>
26+
</ItemGroup>
2727

2828
</Project>

UtilityGenerators/AttributeFactory/AttributeFactoryGenerator.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2238,7 +2238,7 @@ static void append(in SourceBuildingContext ctx, IList<PropertyModel> properties
22382238
.Append("if(kvp.Value.TryGet").Append(property.Type.KindString).Append("Value(out ").Append(property.Type.NullableDisplayString).AppendLine(" value))")
22392239
.Indent().Append(property.Name).AppendCore(" = value");
22402240

2241-
if(property.Type.Kind.HasAnyFlagFast(AttributeParameterTypeKind.ValueType, AttributeParameterTypeKind.Enum))
2241+
if(property.Type.Kind.HasAnyFlagFast(AttributeParameterTypeKind.ValueType, AttributeParameterTypeKind.Enum, AttributeParameterTypeKind.TypeArray, AttributeParameterTypeKind.NullableTypeArray))
22422242
ctx.SourceBuilder.AppendCore(".Value");
22432243

22442244
ctx.SourceBuilder.AppendLine(';').Detent()
Lines changed: 93 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
11
// SPDX-License-Identifier: MPL-2.0
22

33
namespace RhoMicro.CodeAnalysis.Library.Models;
4-
using System;
54

5+
using System;
66
using Microsoft.CodeAnalysis;
77

88
#if RHOMICRO_CODEANALYSIS_UTILITYGENERATORS
99
[IncludeFile]
1010
#endif
1111
internal sealed record AttributeParameterTypeModel(
12-
AttributeParameterTypeKind Kind,
13-
String KindString,
14-
String DisplayString,
15-
String ElementDisplayString,
16-
String NullableDisplayString)
12+
AttributeParameterTypeKind Kind,
13+
String KindString,
14+
String DisplayString,
15+
String ElementDisplayString,
16+
String NullableDisplayString)
1717
{
1818
private const String _typeSymbolDisplayString = "global::Microsoft.CodeAnalysis.ITypeSymbol";
1919
private const String _nullableTypeSymbolDisplayString = "global::Microsoft.CodeAnalysis.ITypeSymbol?";
@@ -29,20 +29,20 @@ public static AttributeParameterTypeModel Create(ITypeSymbol type, in ModelCreat
2929
var isTypeNullableAnnotated = type.NullableAnnotation == NullableAnnotation.Annotated;
3030

3131
// value type?
32-
if(type.IsValueType)
32+
if (type.IsValueType)
3333
{
3434
// enum?
3535
kind = type.BaseType is { SpecialType: SpecialType.System_Enum }
36-
? AttributeParameterTypeKind.Enum
37-
: AttributeParameterTypeKind.ValueType;
36+
? AttributeParameterTypeKind.Enum
37+
: AttributeParameterTypeKind.ValueType;
3838

3939
displayString = elementDisplayString = ToDisplayString(type);
4040
}
4141
// type?
42-
else if(IsType(type))
42+
else if (IsType(type))
4343
{
4444
// nullable type?
45-
if(isTypeNullableAnnotated)
45+
if (isTypeNullableAnnotated)
4646
{
4747
kind = AttributeParameterTypeKind.NullableType;
4848
displayString = elementDisplayString = _nullableTypeSymbolDisplayString;
@@ -55,58 +55,73 @@ public static AttributeParameterTypeModel Create(ITypeSymbol type, in ModelCreat
5555
}
5656
}
5757
// array?
58-
else if(type is IArrayTypeSymbol array)
58+
else if (type is IArrayTypeSymbol array)
5959
{
6060
var elementType = array.ElementType;
6161
var isElementTypeNullableAnnotated = elementType.NullableAnnotation == NullableAnnotation.Annotated;
6262

6363
// nullable array?
64-
if(isTypeNullableAnnotated)
64+
if (isTypeNullableAnnotated)
6565
{
6666
// value type nullable array?
67-
if(elementType.IsValueType)
67+
if (elementType.IsValueType)
6868
{
6969
// enum nullable array?
7070
kind = elementType.BaseType is { SpecialType: SpecialType.System_Enum }
71-
? AttributeParameterTypeKind.EnumNullableArray
72-
: AttributeParameterTypeKind.ValueTypeNullableArray;
71+
? AttributeParameterTypeKind.EnumNullableArray
72+
: AttributeParameterTypeKind.ValueTypeNullableArray;
7373

74-
displayString = ToArrayDisplayString(elementType, nullable: true);
74+
displayString = ToArrayDisplayString(
75+
elementType,
76+
nullable: true,
77+
isTypeElement: false);
7578
elementDisplayString = ToDisplayString(elementType);
7679
}
7780
// type nullable array?
78-
else if(IsType(elementType))
81+
else if (IsType(elementType))
7982
{
8083
// nullable type nullable array?
81-
if(isElementTypeNullableAnnotated)
84+
if (isElementTypeNullableAnnotated)
8285
{
8386
kind = AttributeParameterTypeKind.NullableTypeNullableArray;
84-
displayString = ToArrayDisplayString(_nullableTypeSymbolDisplayString, nullable: true);
87+
displayString = ToArrayDisplayString(
88+
_nullableTypeSymbolDisplayString,
89+
nullable: true,
90+
isTypeElement: true);
8591
elementDisplayString = _nullableTypeSymbolDisplayString;
8692
}
8793
// type nullable array
8894
else
8995
{
9096
kind = AttributeParameterTypeKind.TypeNullableArray;
91-
displayString = ToArrayDisplayString(_typeSymbolDisplayString, nullable: true);
97+
displayString = ToArrayDisplayString(
98+
_typeSymbolDisplayString,
99+
nullable: true,
100+
isTypeElement: true);
92101
elementDisplayString = _typeSymbolDisplayString;
93102
}
94103
}
95104
// reference type nullable array
96105
else
97106
{
98107
// nullable reference type nullable array?
99-
if(isElementTypeNullableAnnotated)
108+
if (isElementTypeNullableAnnotated)
100109
{
101110
kind = AttributeParameterTypeKind.NullableReferenceTypeNullableArray;
102-
displayString = ToArrayDisplayString(elementType, nullable: true);
111+
displayString = ToArrayDisplayString(
112+
elementType,
113+
nullable: true,
114+
isTypeElement: false);
103115
elementDisplayString = ToDisplayString(elementType);
104116
}
105117
// reference type nullable array
106118
else
107119
{
108120
kind = AttributeParameterTypeKind.ReferenceTypeNullableArray;
109-
displayString = ToArrayDisplayString(elementType, nullable: true);
121+
displayString = ToArrayDisplayString(
122+
elementType,
123+
nullable: true,
124+
isTypeElement: false);
110125
elementDisplayString = ToDisplayString(elementType);
111126
}
112127
}
@@ -115,49 +130,61 @@ public static AttributeParameterTypeModel Create(ITypeSymbol type, in ModelCreat
115130
else
116131
{
117132
// value type array?
118-
if(elementType.IsValueType)
133+
if (elementType.IsValueType)
119134
{
120135
// enum nullable array?
121136
kind = elementType.BaseType is { SpecialType: SpecialType.System_Enum }
122-
? AttributeParameterTypeKind.EnumArray
123-
: AttributeParameterTypeKind.ValueTypeArray;
137+
? AttributeParameterTypeKind.EnumArray
138+
: AttributeParameterTypeKind.ValueTypeArray;
124139

125-
displayString = ToArrayDisplayString(elementType, nullable: false);
140+
displayString = ToArrayDisplayString(
141+
elementType,
142+
nullable: false,
143+
isTypeElement: false);
126144
elementDisplayString = ToDisplayString(elementType);
127145
}
128146
// type array?
129-
else if(IsType(elementType))
147+
else if (IsType(elementType))
130148
{
131149
// nullable type array?
132-
if(isElementTypeNullableAnnotated)
150+
if (isElementTypeNullableAnnotated)
133151
{
134152
kind = AttributeParameterTypeKind.NullableTypeArray;
135-
displayString = ToArrayDisplayString(_nullableTypeSymbolDisplayString, nullable: false);
153+
displayString = ToArrayDisplayString(
154+
_nullableTypeSymbolDisplayString,
155+
nullable: false,
156+
isTypeElement: true);
136157
elementDisplayString = _nullableTypeSymbolDisplayString;
137158
}
138159
// type array
139160
else
140161
{
141162
kind = AttributeParameterTypeKind.TypeArray;
142-
displayString = ToArrayDisplayString(_typeSymbolDisplayString, nullable: false);
163+
displayString = ToArrayDisplayString(
164+
_typeSymbolDisplayString,
165+
nullable: false,
166+
isTypeElement: true);
143167
elementDisplayString = _nullableTypeSymbolDisplayString;
144168
}
145169
}
146170
// reference type array
147171
else
148172
{
149173
// nullable reference type array?
150-
if(isElementTypeNullableAnnotated)
174+
if (isElementTypeNullableAnnotated)
151175
{
152176
kind = AttributeParameterTypeKind.NullableReferenceTypeArray;
153-
displayString = ToArrayDisplayString(elementType, nullable: false);
177+
displayString = ToArrayDisplayString(
178+
elementType,
179+
nullable: false,
180+
isTypeElement: false);
154181
elementDisplayString = ToDisplayString(elementType);
155182
}
156183
// reference type array?
157184
else
158185
{
159186
kind = AttributeParameterTypeKind.ReferenceTypeArray;
160-
displayString = ToArrayDisplayString(elementType, nullable: false);
187+
displayString = ToArrayDisplayString(elementType, nullable: false, isTypeElement: false);
161188
elementDisplayString = ToDisplayString(elementType);
162189
}
163190
}
@@ -167,7 +194,7 @@ public static AttributeParameterTypeModel Create(ITypeSymbol type, in ModelCreat
167194
else
168195
{
169196
// nullable reference type
170-
if(isTypeNullableAnnotated)
197+
if (isTypeNullableAnnotated)
171198
{
172199
kind = AttributeParameterTypeKind.NullableReferenceType;
173200
displayString = elementDisplayString = ToDisplayString(type);
@@ -182,27 +209,41 @@ public static AttributeParameterTypeModel Create(ITypeSymbol type, in ModelCreat
182209

183210
var kindString = kind.ToStringFast();
184211
var nullableDisplayString =
185-
kind.HasAnyFlagFast(AttributeParameterTypeKind.NullableArray)
186-
|| !kind.HasAnyFlagFast(AttributeParameterTypeKind.Array)
187-
&& kind.HasAnyFlagFast(AttributeParameterTypeKind.Nullable)
188-
? displayString
189-
: $"{displayString}?";
212+
kind.HasAnyFlagFast(AttributeParameterTypeKind.NullableArray)
213+
|| !kind.HasAnyFlagFast(AttributeParameterTypeKind.Array)
214+
&& kind.HasAnyFlagFast(AttributeParameterTypeKind.Nullable)
215+
? displayString
216+
: $"{displayString}?";
190217

191218
var result = new AttributeParameterTypeModel(
192-
kind,
193-
KindString: kindString,
194-
DisplayString: displayString,
195-
ElementDisplayString: elementDisplayString,
196-
NullableDisplayString: nullableDisplayString);
219+
kind,
220+
KindString: kindString,
221+
DisplayString: displayString,
222+
ElementDisplayString: elementDisplayString,
223+
NullableDisplayString: nullableDisplayString);
197224

198225
return result;
199226
}
200-
private static String ToDisplayString(ITypeSymbol type) => type.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat);
201-
private static String ToArrayDisplayString(String elementType, Boolean nullable) => $"global::RhoMicro.CodeAnalysis.Library.Models.Collections.EquatableList<{elementType}>{( nullable ? "?" : "" )}";
202-
private static String ToArrayDisplayString(ITypeSymbol elementType, Boolean nullable) => ToArrayDisplayString(elementType.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat), nullable);
203-
private static Boolean IsType(ITypeSymbol type) => type is { Name: "Type", ContainingNamespace: { Name: "System", ContainingNamespace: { IsGlobalNamespace: true } } };
227+
228+
private static String ToDisplayString(ITypeSymbol type) =>
229+
type.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat);
230+
231+
private static String ToArrayDisplayString(String elementType, Boolean nullable, Boolean isTypeElement) =>
232+
$"{(isTypeElement
233+
? "global::System.Collections.Immutable.ImmutableArray"
234+
: "global::RhoMicro.CodeAnalysis.Library.Models.Collections.EquatableList")}<{elementType}>{(nullable
235+
? "?"
236+
: "")}";
237+
238+
private static String ToArrayDisplayString(ITypeSymbol elementType, Boolean nullable, Boolean isTypeElement) =>
239+
ToArrayDisplayString(elementType.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat), nullable,
240+
isTypeElement);
241+
242+
private static Boolean IsType(ITypeSymbol type) => type is
243+
{ Name: "Type", ContainingNamespace: { Name: "System", ContainingNamespace: { IsGlobalNamespace: true } } };
204244

205245
public override Int32 GetHashCode() => DisplayString.GetHashCode();
206-
public Boolean Equals(AttributeParameterTypeModel other) => DisplayString.Equals(other.DisplayString);
207-
}
208246

247+
public Boolean Equals(AttributeParameterTypeModel? other) =>
248+
other is not null && DisplayString.Equals(other.DisplayString);
249+
}

UtilityGenerators/UtilityGenerators.csproj

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
<InternalsVisibleTo Include="RhoMicro.CodeAnalysis.UtilityGenerators.Tests" />
1616
<InternalsVisibleTo Include="UtilityGenerators.Benchmarks" />
1717
</ItemGroup>
18-
18+
1919
<PropertyGroup>
2020
<IsPackable>true</IsPackable>
2121
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
@@ -28,7 +28,7 @@
2828
<PropertyGroup>
2929
<DefineConstants>$(DefineConstants);GENERATOR;RHOMICRO_CODEANALYSIS_UTILITYGENERATORS</DefineConstants>
3030
</PropertyGroup>
31-
31+
3232
<ItemGroup>
3333
<PackageReference Update="NETStandard.Library" PrivateAssets="all" />
3434
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.12.0" />
@@ -41,11 +41,7 @@
4141
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
4242
</PackageReference>
4343
</ItemGroup>
44-
45-
<ItemGroup>
46-
<None Remove=".editorconfig"></None>
47-
</ItemGroup>
48-
44+
4945
<ItemGroup>
5046
<None Remove="bin\Release\netstandard2.0\\RhoMicro.CodeAnalysis.UtilityGenerators.1.0.0.dll" />
5147
</ItemGroup>
2.69 KB
Binary file not shown.

0 commit comments

Comments
 (0)