Skip to content

Commit 74939c5

Browse files
committed
fix to validate arguments
1 parent d9e4200 commit 74939c5

File tree

2 files changed

+109
-5
lines changed
  • src/Smdn.Reflection.ReverseGenerating/Smdn.Reflection.ReverseGenerating
  • tests/Smdn.Reflection.ReverseGenerating/Smdn.Reflection.ReverseGenerating

2 files changed

+109
-5
lines changed

src/Smdn.Reflection.ReverseGenerating/Smdn.Reflection.ReverseGenerating/Generator.cs

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,33 @@
1212
namespace Smdn.Reflection.ReverseGenerating;
1313

1414
public static partial class Generator {
15+
private static Type GenerateDeclarationValidateTypeArgument(Type? t, string paramName)
16+
{
17+
if (t is null)
18+
throw new ArgumentNullException(paramName);
19+
if (t.IsConstructedGenericType)
20+
throw new ArgumentException($"can not generate declaration of constructed generic types (type: {t})");
21+
22+
return t;
23+
}
24+
25+
private static Type GenerateDeclarationValidateGenericParameterArgument(Type? genericParameter, string paramName)
26+
{
27+
if (genericParameter is null)
28+
throw new ArgumentNullException(paramName);
29+
if (!genericParameter.IsGenericParameter)
30+
throw new ArgumentException($"can not generate declaration of types which does not represent generic parameter ({genericParameter.FullName})");
31+
32+
return genericParameter;
33+
}
34+
1535
public static string GenerateTypeDeclaration(
1636
Type t,
1737
ISet<string>? referencingNamespaces,
1838
GeneratorOptions options
1939
) =>
2040
GenerateTypeDeclaration(
21-
t,
41+
GenerateDeclarationValidateTypeArgument(t, nameof(t)),
2242
false,
2343
referencingNamespaces,
2444
options ?? throw new ArgumentNullException(nameof(options))
@@ -30,7 +50,7 @@ public static IEnumerable<string> GenerateTypeDeclarationWithExplicitBaseTypeAnd
3050
GeneratorOptions options
3151
) =>
3252
GenerateTypeDeclaration(
33-
t,
53+
GenerateDeclarationValidateTypeArgument(t, nameof(t)),
3454
true,
3555
referencingNamespaces,
3656
options ?? throw new ArgumentNullException(nameof(options))
@@ -148,7 +168,7 @@ public static string GenerateGenericArgumentConstraintDeclaration(
148168
GeneratorOptions options
149169
)
150170
=> GenerateGenericParameterConstraintDeclaration(
151-
genericParameter: genericArgument,
171+
genericParameter: GenerateDeclarationValidateGenericParameterArgument(genericArgument, nameof(genericArgument)),
152172
referencingNamespaces: referencingNamespaces,
153173
options: options
154174
);
@@ -159,6 +179,11 @@ public static string GenerateGenericParameterConstraintDeclaration(
159179
GeneratorOptions options
160180
)
161181
{
182+
GenerateDeclarationValidateGenericParameterArgument(genericParameter, nameof(genericParameter));
183+
184+
if (options is null)
185+
throw new ArgumentNullException(nameof(options));
186+
162187
static bool HasUnmanagedConstraint(Type genericParameter)
163188
=> genericParameter.CustomAttributes.Any(
164189
static attr => attr.AttributeType.FullName.Equals("System.Runtime.CompilerServices.IsUnmanagedAttribute", StringComparison.Ordinal)
@@ -244,6 +269,8 @@ public static IEnumerable<string> GenerateExplicitBaseTypeAndInterfaces(
244269
GeneratorOptions options
245270
)
246271
{
272+
if (t is null)
273+
throw new ArgumentNullException(nameof(t));
247274
if (options == null)
248275
throw new ArgumentNullException(nameof(options));
249276

@@ -678,7 +705,10 @@ GeneratorOptions options
678705
{
679706
MethodInfo? explicitInterfaceMethod = null;
680707

681-
if (!asDelegateDeclaration) {
708+
if (asDelegateDeclaration) {
709+
GenerateDeclarationValidateTypeArgument(m.GetDeclaringTypeOrThrow(), nameof(m));
710+
}
711+
else {
682712
var isExplicitInterfaceMethod = m.TryFindExplicitInterfaceMethod(
683713
out explicitInterfaceMethod,
684714
findOnlyPublicInterfaces: options.IgnorePrivateOrAssembly
@@ -744,7 +774,9 @@ GeneratorOptions options
744774
? null
745775
: asDelegateDeclaration
746776
? m.GetDeclaringTypeOrThrow().GetGenericArguments()
747-
: method.GetGenericArguments();
777+
: method.IsGenericMethodDefinition
778+
? method.GetGenericArguments()
779+
: null;
748780
var methodConstraints = genericParameters is null
749781
? null
750782
: string.Join(

tests/Smdn.Reflection.ReverseGenerating/Smdn.Reflection.ReverseGenerating/Generator.cs

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,4 +176,76 @@ private static GeneratorOptions GetGeneratorOptions(GeneratorTestCaseAttribute t
176176

177177
return options;
178178
}
179+
180+
[Test]
181+
public void GenerateTypeDeclaration_ArgumentOptionsNull()
182+
=> Assert.Throws<ArgumentNullException>(() => Generator.GenerateTypeDeclaration(t: typeof(int), null, options: null!));
183+
184+
[Test]
185+
public void GenerateTypeDeclaration_ArgumentTypeNull()
186+
=> Assert.Throws<ArgumentNullException>(() => Generator.GenerateTypeDeclaration(t: null!, null, options: new()));
187+
188+
[TestCase(typeof(List<int>))]
189+
[TestCase(typeof(IEnumerable<int>))]
190+
[TestCase(typeof(Action<int>))]
191+
[TestCase(typeof(int?))]
192+
[TestCase(typeof((int, int)))]
193+
public void GenerateTypeDeclaration_ArgumentTypeIsConstructedGenericType(Type type)
194+
=> Assert.Throws<ArgumentException>(() => Generator.GenerateTypeDeclaration(t: type, null, options: new()));
195+
196+
[Test]
197+
public void GenerateTypeDeclarationWithExplicitBaseTypeAndInterfaces_ArgumentOptionsNull()
198+
=> Assert.Throws<ArgumentNullException>(() => Generator.GenerateTypeDeclarationWithExplicitBaseTypeAndInterfaces(t: typeof(int), null, options: null!));
199+
200+
[Test]
201+
public void GenerateTypeDeclarationWithExplicitBaseTypeAndInterfaces_ArgumentTypeNull()
202+
=> Assert.Throws<ArgumentNullException>(() => Generator.GenerateTypeDeclarationWithExplicitBaseTypeAndInterfaces(t: null!, null, options: new()));
203+
204+
[TestCase(typeof(List<int>))]
205+
[TestCase(typeof(IEnumerable<int>))]
206+
[TestCase(typeof(Action<int>))]
207+
[TestCase(typeof(int?))]
208+
[TestCase(typeof((int, int)))]
209+
public void GenerateTypeDeclarationWithExplicitBaseTypeAndInterfaces_ArgumentTypeIsConstructedGenericType(Type type)
210+
=> Assert.Throws<ArgumentException>(() => Generator.GenerateTypeDeclarationWithExplicitBaseTypeAndInterfaces(t: type, null, options: new()));
211+
212+
[Test]
213+
public void GenerateMemberDeclaration_ArgumentOptionsNull()
214+
=> Assert.Throws<ArgumentNullException>(() => Generator.GenerateMemberDeclaration(member: typeof(int).GetMembers().First(), null, options: null!));
215+
216+
[Test]
217+
public void GenerateMemberDeclaration_ArgumentTypeNull()
218+
=> Assert.Throws<ArgumentNullException>(() => Generator.GenerateMemberDeclaration(member: null!, null, options: new()));
219+
220+
[Test]
221+
public void GenerateGenericParameterConstraintDeclaration_ArgumentOptionsNull()
222+
{
223+
var genericParameter = typeof(List<>).GetGenericArguments()[0];
224+
225+
Assert.Throws<ArgumentNullException>(() => Generator.GenerateGenericParameterConstraintDeclaration(genericParameter: genericParameter, null, options: null!));
226+
}
227+
228+
[Test]
229+
public void GenerateGenericParameterConstraintDeclaration_ArgumentGenericParameterNull()
230+
=> Assert.Throws<ArgumentNullException>(() => Generator.GenerateGenericParameterConstraintDeclaration(genericParameter: null!, null, options: new()));
231+
232+
[TestCase(typeof(int))]
233+
[TestCase(typeof(List<>))]
234+
public void GenerateGenericParameterConstraintDeclaration_ArgumentGenericParameterIsType(Type type)
235+
=> Assert.Throws<ArgumentException>(() => Generator.GenerateGenericParameterConstraintDeclaration(genericParameter: type, null, options: new()));
236+
237+
[TestCase(typeof(List<int>))]
238+
[TestCase(typeof(Action<int>))]
239+
[TestCase(typeof(int?))]
240+
[TestCase(typeof((int, int)))]
241+
public void GenerateGenericParameterConstraintDeclaration_ArgumentGenericParameterIsGenericArgument(Type type)
242+
=> Assert.Throws<ArgumentException>(() => Generator.GenerateGenericParameterConstraintDeclaration(genericParameter: type.GetGenericArguments()[0], null, options: new()));
243+
244+
[Test]
245+
public void GenerateExplicitBaseTypeAndInterfaces_ArgumentOptionsNull()
246+
=> Assert.Throws<ArgumentNullException>(() => Generator.GenerateExplicitBaseTypeAndInterfaces(t: typeof(int), null, options: null!));
247+
248+
[Test]
249+
public void GenerateExplicitBaseTypeAndInterfaces_ArgumentTypeNull()
250+
=> Assert.Throws<ArgumentNullException>(() => Generator.GenerateExplicitBaseTypeAndInterfaces(t: null!, null, options: new()));
179251
}

0 commit comments

Comments
 (0)