Skip to content

Commit efd3e92

Browse files
authored
Merge pull request #2535 from vweijsters/implement-2388
Implemented missing parameter validation in separated syntax list acc…
2 parents 4bd51d2 + 6fb80e4 commit efd3e92

24 files changed

Lines changed: 307 additions & 234 deletions
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// Copyright (c) Tunnel Vision Laboratories, LLC. All Rights Reserved.
2+
// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.
3+
4+
namespace StyleCop.Analyzers.Test.CSharp7.Lightup
5+
{
6+
using System.Linq;
7+
using System.Reflection;
8+
using StyleCop.Analyzers.Lightup;
9+
using Xunit;
10+
11+
public class WrapperHelperTests
12+
{
13+
[Fact]
14+
public void VerifyThatAllWrapperClassesArePresent()
15+
{
16+
var wrapperTypes = typeof(ISyntaxWrapper<>).Assembly.GetTypes()
17+
.Where(t => t.GetTypeInfo().ImplementedInterfaces.Any(i => i.IsGenericType && (i.GetGenericTypeDefinition() == typeof(ISyntaxWrapper<>))));
18+
19+
foreach (var wrapperType in wrapperTypes)
20+
{
21+
var wrappedType = WrapperHelper.GetWrappedType(wrapperType);
22+
Assert.NotNull(wrapperType);
23+
}
24+
}
25+
}
26+
}

StyleCop.Analyzers/StyleCop.Analyzers.Test/Lightup/LightupHelpersTests.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ public void TestCreateSeparatedSyntaxListPropertyAccessor()
6767
Assert.ThrowsAny<InvalidOperationException>(() => LightupHelpers.CreateSeparatedSyntaxListPropertyAccessor<ParameterListSyntax, ParameterSyntax>(typeof(BaseParameterListSyntax), nameof(BaseParameterListSyntax.Parameters)));
6868
}
6969

70-
[Fact(Skip = "Validation is not currently performed for the second argument.")]
70+
[Fact]
7171
public void TestCreateSeparatedSyntaxListPropertyAccessorValidateElementType()
7272
{
7373
// The call *should* have been made with the second generic argument set to `ParameterSyntax`
@@ -98,7 +98,7 @@ public void TestCreateSeparatedSyntaxListWithPropertyAccessor()
9898
Assert.ThrowsAny<InvalidOperationException>(() => LightupHelpers.CreateSeparatedSyntaxListWithPropertyAccessor<ParameterListSyntax, ParameterSyntax>(typeof(BaseParameterListSyntax), nameof(BaseParameterListSyntax.Parameters)));
9999
}
100100

101-
[Fact(Skip = "Validation is not currently performed for the second argument.")]
101+
[Fact]
102102
public void TestCreateSeparatedSyntaxListWithPropertyAccessorValidateElementType()
103103
{
104104
// The call *should* have been made with the second generic argument set to `ParameterSyntax`

StyleCop.Analyzers/StyleCop.Analyzers/Lightup/CasePatternSwitchLabelSyntaxWrapper.cs

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,14 @@
44
namespace StyleCop.Analyzers.Lightup
55
{
66
using System;
7-
using System.Reflection;
87
using Microsoft.CodeAnalysis;
98
using Microsoft.CodeAnalysis.CSharp;
109
using Microsoft.CodeAnalysis.CSharp.Syntax;
1110

1211
internal struct CasePatternSwitchLabelSyntaxWrapper : ISyntaxWrapper<SwitchLabelSyntax>
1312
{
14-
private const string CasePatternSwitchLabelSyntaxTypeName = "Microsoft.CodeAnalysis.CSharp.Syntax.CasePatternSwitchLabelSyntax";
15-
private static readonly Type CasePatternSwitchLabelSyntaxType;
13+
internal const string WrappedTypeName = "Microsoft.CodeAnalysis.CSharp.Syntax.CasePatternSwitchLabelSyntax";
14+
private static readonly Type WrappedType;
1615

1716
private static readonly Func<SwitchLabelSyntax, CSharpSyntaxNode> PatternAccessor;
1817
private static readonly Func<SwitchLabelSyntax, CSharpSyntaxNode> WhenClauseAccessor;
@@ -25,13 +24,13 @@ internal struct CasePatternSwitchLabelSyntaxWrapper : ISyntaxWrapper<SwitchLabel
2524

2625
static CasePatternSwitchLabelSyntaxWrapper()
2726
{
28-
CasePatternSwitchLabelSyntaxType = typeof(CSharpSyntaxNode).GetTypeInfo().Assembly.GetType(CasePatternSwitchLabelSyntaxTypeName);
29-
PatternAccessor = LightupHelpers.CreateSyntaxPropertyAccessor<SwitchLabelSyntax, CSharpSyntaxNode>(CasePatternSwitchLabelSyntaxType, nameof(Pattern));
30-
WhenClauseAccessor = LightupHelpers.CreateSyntaxPropertyAccessor<SwitchLabelSyntax, CSharpSyntaxNode>(CasePatternSwitchLabelSyntaxType, nameof(WhenClause));
31-
WithKeywordAccessor = LightupHelpers.CreateSyntaxWithPropertyAccessor<SwitchLabelSyntax, SyntaxToken>(CasePatternSwitchLabelSyntaxType, nameof(SwitchLabelSyntax.Keyword));
32-
WithColonTokenAccessor = LightupHelpers.CreateSyntaxWithPropertyAccessor<SwitchLabelSyntax, SyntaxToken>(CasePatternSwitchLabelSyntaxType, nameof(SwitchLabelSyntax.ColonToken));
33-
WithPatternAccessor = LightupHelpers.CreateSyntaxWithPropertyAccessor<SwitchLabelSyntax, CSharpSyntaxNode>(CasePatternSwitchLabelSyntaxType, nameof(Pattern));
34-
WithWhenClauseAccessor = LightupHelpers.CreateSyntaxWithPropertyAccessor<SwitchLabelSyntax, CSharpSyntaxNode>(CasePatternSwitchLabelSyntaxType, nameof(WhenClause));
27+
WrappedType = WrapperHelper.GetWrappedType(typeof(CasePatternSwitchLabelSyntaxWrapper));
28+
PatternAccessor = LightupHelpers.CreateSyntaxPropertyAccessor<SwitchLabelSyntax, CSharpSyntaxNode>(WrappedType, nameof(Pattern));
29+
WhenClauseAccessor = LightupHelpers.CreateSyntaxPropertyAccessor<SwitchLabelSyntax, CSharpSyntaxNode>(WrappedType, nameof(WhenClause));
30+
WithKeywordAccessor = LightupHelpers.CreateSyntaxWithPropertyAccessor<SwitchLabelSyntax, SyntaxToken>(WrappedType, nameof(SwitchLabelSyntax.Keyword));
31+
WithColonTokenAccessor = LightupHelpers.CreateSyntaxWithPropertyAccessor<SwitchLabelSyntax, SyntaxToken>(WrappedType, nameof(SwitchLabelSyntax.ColonToken));
32+
WithPatternAccessor = LightupHelpers.CreateSyntaxWithPropertyAccessor<SwitchLabelSyntax, CSharpSyntaxNode>(WrappedType, nameof(Pattern));
33+
WithWhenClauseAccessor = LightupHelpers.CreateSyntaxWithPropertyAccessor<SwitchLabelSyntax, CSharpSyntaxNode>(WrappedType, nameof(WhenClause));
3534
}
3635

3736
private CasePatternSwitchLabelSyntaxWrapper(SwitchLabelSyntax node)
@@ -66,7 +65,7 @@ public static explicit operator CasePatternSwitchLabelSyntaxWrapper(SyntaxNode n
6665

6766
if (!IsInstance(node))
6867
{
69-
throw new InvalidCastException($"Cannot cast '{node.GetType().FullName}' to '{CasePatternSwitchLabelSyntaxTypeName}'");
68+
throw new InvalidCastException($"Cannot cast '{node.GetType().FullName}' to '{WrappedTypeName}'");
7069
}
7170

7271
return new CasePatternSwitchLabelSyntaxWrapper((SwitchLabelSyntax)node);
@@ -79,7 +78,7 @@ public static implicit operator SwitchLabelSyntax(CasePatternSwitchLabelSyntaxWr
7978

8079
public static bool IsInstance(SyntaxNode node)
8180
{
82-
return node != null && LightupHelpers.CanWrapNode(node, CasePatternSwitchLabelSyntaxType);
81+
return node != null && LightupHelpers.CanWrapNode(node, WrappedType);
8382
}
8483

8584
public CasePatternSwitchLabelSyntaxWrapper WithKeyword(SyntaxToken keyword)

StyleCop.Analyzers/StyleCop.Analyzers/Lightup/CommonForEachStatementSyntaxWrapper.cs

Lines changed: 12 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,14 @@
44
namespace StyleCop.Analyzers.Lightup
55
{
66
using System;
7-
using System.Reflection;
87
using Microsoft.CodeAnalysis;
9-
using Microsoft.CodeAnalysis.CSharp;
108
using Microsoft.CodeAnalysis.CSharp.Syntax;
119

1210
internal struct CommonForEachStatementSyntaxWrapper : ISyntaxWrapper<StatementSyntax>
1311
{
14-
private const string CommonForEachStatementSyntaxTypeName = "Microsoft.CodeAnalysis.CSharp.Syntax.CommonForEachStatementSyntax";
15-
16-
/// <summary>
17-
/// Prior to C# 7, <see cref="ForEachStatementSyntax"/> was the base type for all <c>foreach</c> statements. If
18-
/// the <c>CommonForEachStatementSyntax</c> type isn't found at runtime, we fall back to using this type
19-
/// instead.
20-
/// </summary>
21-
private const string ForEachStatementSyntaxTypeName = "Microsoft.CodeAnalysis.CSharp.Syntax.CommonForEachStatementSyntax";
22-
23-
private static readonly Type CommonForEachStatementSyntaxType;
12+
internal const string WrappedTypeName = "Microsoft.CodeAnalysis.CSharp.Syntax.CommonForEachStatementSyntax";
13+
internal const string FallbackWrappedTypeName = "Microsoft.CodeAnalysis.CSharp.Syntax.ForEachStatementSyntax";
14+
private static readonly Type WrappedType;
2415

2516
private static readonly Func<StatementSyntax, SyntaxToken> ForEachKeywordAccessor;
2617
private static readonly Func<StatementSyntax, SyntaxToken> OpenParenTokenAccessor;
@@ -33,14 +24,13 @@ internal struct CommonForEachStatementSyntaxWrapper : ISyntaxWrapper<StatementSy
3324

3425
static CommonForEachStatementSyntaxWrapper()
3526
{
36-
CommonForEachStatementSyntaxType = typeof(CSharpSyntaxNode).GetTypeInfo().Assembly.GetType(CommonForEachStatementSyntaxTypeName)
37-
?? typeof(CSharpSyntaxNode).GetTypeInfo().Assembly.GetType(ForEachStatementSyntaxTypeName);
38-
ForEachKeywordAccessor = LightupHelpers.CreateSyntaxPropertyAccessor<StatementSyntax, SyntaxToken>(CommonForEachStatementSyntaxType, nameof(ForEachKeyword));
39-
OpenParenTokenAccessor = LightupHelpers.CreateSyntaxPropertyAccessor<StatementSyntax, SyntaxToken>(CommonForEachStatementSyntaxType, nameof(OpenParenToken));
40-
InKeywordAccessor = LightupHelpers.CreateSyntaxPropertyAccessor<StatementSyntax, SyntaxToken>(CommonForEachStatementSyntaxType, nameof(InKeyword));
41-
ExpressionAccessor = LightupHelpers.CreateSyntaxPropertyAccessor<StatementSyntax, ExpressionSyntax>(CommonForEachStatementSyntaxType, nameof(Expression));
42-
CloseParenTokenAccessor = LightupHelpers.CreateSyntaxPropertyAccessor<StatementSyntax, SyntaxToken>(CommonForEachStatementSyntaxType, nameof(CloseParenToken));
43-
StatementAccessor = LightupHelpers.CreateSyntaxPropertyAccessor<StatementSyntax, StatementSyntax>(CommonForEachStatementSyntaxType, nameof(Statement));
27+
WrappedType = WrapperHelper.GetWrappedType(typeof(CommonForEachStatementSyntaxWrapper));
28+
ForEachKeywordAccessor = LightupHelpers.CreateSyntaxPropertyAccessor<StatementSyntax, SyntaxToken>(WrappedType, nameof(ForEachKeyword));
29+
OpenParenTokenAccessor = LightupHelpers.CreateSyntaxPropertyAccessor<StatementSyntax, SyntaxToken>(WrappedType, nameof(OpenParenToken));
30+
InKeywordAccessor = LightupHelpers.CreateSyntaxPropertyAccessor<StatementSyntax, SyntaxToken>(WrappedType, nameof(InKeyword));
31+
ExpressionAccessor = LightupHelpers.CreateSyntaxPropertyAccessor<StatementSyntax, ExpressionSyntax>(WrappedType, nameof(Expression));
32+
CloseParenTokenAccessor = LightupHelpers.CreateSyntaxPropertyAccessor<StatementSyntax, SyntaxToken>(WrappedType, nameof(CloseParenToken));
33+
StatementAccessor = LightupHelpers.CreateSyntaxPropertyAccessor<StatementSyntax, StatementSyntax>(WrappedType, nameof(Statement));
4434
}
4535

4636
private CommonForEachStatementSyntaxWrapper(StatementSyntax node)
@@ -112,7 +102,7 @@ public static explicit operator CommonForEachStatementSyntaxWrapper(SyntaxNode n
112102

113103
if (!IsInstance(node))
114104
{
115-
throw new InvalidCastException($"Cannot cast '{node.GetType().FullName}' to '{CommonForEachStatementSyntaxTypeName}'");
105+
throw new InvalidCastException($"Cannot cast '{node.GetType().FullName}' to '{WrappedTypeName}'");
116106
}
117107

118108
return new CommonForEachStatementSyntaxWrapper((StatementSyntax)node);
@@ -125,7 +115,7 @@ public static implicit operator StatementSyntax(CommonForEachStatementSyntaxWrap
125115

126116
public static bool IsInstance(SyntaxNode node)
127117
{
128-
return node != null && LightupHelpers.CanWrapNode(node, CommonForEachStatementSyntaxType);
118+
return node != null && LightupHelpers.CanWrapNode(node, WrappedType);
129119
}
130120

131121
internal static CommonForEachStatementSyntaxWrapper FromUpcast(StatementSyntax node)

StyleCop.Analyzers/StyleCop.Analyzers/Lightup/ConstantPatternSyntaxWrapper.cs

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,14 @@
44
namespace StyleCop.Analyzers.Lightup
55
{
66
using System;
7-
using System.Reflection;
87
using Microsoft.CodeAnalysis;
98
using Microsoft.CodeAnalysis.CSharp;
109
using Microsoft.CodeAnalysis.CSharp.Syntax;
1110

1211
internal struct ConstantPatternSyntaxWrapper : ISyntaxWrapper<CSharpSyntaxNode>
1312
{
14-
private const string ConstantPatternSyntaxTypeName = "Microsoft.CodeAnalysis.CSharp.Syntax.ConstantPatternSyntax";
15-
private static readonly Type ConstantPatternSyntaxType;
13+
internal const string WrappedTypeName = "Microsoft.CodeAnalysis.CSharp.Syntax.ConstantPatternSyntax";
14+
private static readonly Type WrappedType;
1615

1716
private static readonly Func<CSharpSyntaxNode, ExpressionSyntax> ExpressionAccessor;
1817
private static readonly Func<CSharpSyntaxNode, ExpressionSyntax, CSharpSyntaxNode> WithExpressionAccessor;
@@ -21,9 +20,9 @@ internal struct ConstantPatternSyntaxWrapper : ISyntaxWrapper<CSharpSyntaxNode>
2120

2221
static ConstantPatternSyntaxWrapper()
2322
{
24-
ConstantPatternSyntaxType = typeof(CSharpSyntaxNode).GetTypeInfo().Assembly.GetType(ConstantPatternSyntaxTypeName);
25-
ExpressionAccessor = LightupHelpers.CreateSyntaxPropertyAccessor<CSharpSyntaxNode, ExpressionSyntax>(ConstantPatternSyntaxType, nameof(Expression));
26-
WithExpressionAccessor = LightupHelpers.CreateSyntaxWithPropertyAccessor<CSharpSyntaxNode, ExpressionSyntax>(ConstantPatternSyntaxType, nameof(Expression));
23+
WrappedType = WrapperHelper.GetWrappedType(typeof(ConstantPatternSyntaxWrapper));
24+
ExpressionAccessor = LightupHelpers.CreateSyntaxPropertyAccessor<CSharpSyntaxNode, ExpressionSyntax>(WrappedType, nameof(Expression));
25+
WithExpressionAccessor = LightupHelpers.CreateSyntaxWithPropertyAccessor<CSharpSyntaxNode, ExpressionSyntax>(WrappedType, nameof(Expression));
2726
}
2827

2928
private ConstantPatternSyntaxWrapper(CSharpSyntaxNode node)
@@ -55,7 +54,7 @@ public static explicit operator ConstantPatternSyntaxWrapper(SyntaxNode node)
5554

5655
if (!IsInstance(node))
5756
{
58-
throw new InvalidCastException($"Cannot cast '{node.GetType().FullName}' to '{ConstantPatternSyntaxTypeName}'");
57+
throw new InvalidCastException($"Cannot cast '{node.GetType().FullName}' to '{WrappedTypeName}'");
5958
}
6059

6160
return new ConstantPatternSyntaxWrapper((CSharpSyntaxNode)node);
@@ -73,7 +72,7 @@ public static implicit operator CSharpSyntaxNode(ConstantPatternSyntaxWrapper wr
7372

7473
public static bool IsInstance(SyntaxNode node)
7574
{
76-
return node != null && LightupHelpers.CanWrapNode(node, ConstantPatternSyntaxType);
75+
return node != null && LightupHelpers.CanWrapNode(node, WrappedType);
7776
}
7877

7978
public ConstantPatternSyntaxWrapper WithExpression(ExpressionSyntax expression)

StyleCop.Analyzers/StyleCop.Analyzers/Lightup/DeclarationExpressionSyntaxWrapper.cs

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,14 @@
44
namespace StyleCop.Analyzers.Lightup
55
{
66
using System;
7-
using System.Reflection;
87
using Microsoft.CodeAnalysis;
98
using Microsoft.CodeAnalysis.CSharp;
109
using Microsoft.CodeAnalysis.CSharp.Syntax;
1110

1211
internal struct DeclarationExpressionSyntaxWrapper : ISyntaxWrapper<ExpressionSyntax>
1312
{
14-
private const string DeclarationExpressionSyntaxTypeName = "Microsoft.CodeAnalysis.CSharp.Syntax.DeclarationExpressionSyntax";
15-
private static readonly Type DeclarationExpressionSyntaxType;
13+
internal const string WrappedTypeName = "Microsoft.CodeAnalysis.CSharp.Syntax.DeclarationExpressionSyntax";
14+
private static readonly Type WrappedType;
1615

1716
private static readonly Func<ExpressionSyntax, TypeSyntax> TypeAccessor;
1817
private static readonly Func<ExpressionSyntax, CSharpSyntaxNode> DesignationAccessor;
@@ -23,11 +22,11 @@ internal struct DeclarationExpressionSyntaxWrapper : ISyntaxWrapper<ExpressionSy
2322

2423
static DeclarationExpressionSyntaxWrapper()
2524
{
26-
DeclarationExpressionSyntaxType = typeof(CSharpSyntaxNode).GetTypeInfo().Assembly.GetType(DeclarationExpressionSyntaxTypeName);
27-
TypeAccessor = LightupHelpers.CreateSyntaxPropertyAccessor<ExpressionSyntax, TypeSyntax>(DeclarationExpressionSyntaxType, nameof(Type));
28-
DesignationAccessor = LightupHelpers.CreateSyntaxPropertyAccessor<ExpressionSyntax, CSharpSyntaxNode>(DeclarationExpressionSyntaxType, nameof(Designation));
29-
WithTypeAccessor = LightupHelpers.CreateSyntaxWithPropertyAccessor<ExpressionSyntax, TypeSyntax>(DeclarationExpressionSyntaxType, nameof(Type));
30-
WithDesignationAccessor = LightupHelpers.CreateSyntaxWithPropertyAccessor<ExpressionSyntax, CSharpSyntaxNode>(DeclarationExpressionSyntaxType, nameof(Designation));
25+
WrappedType = WrapperHelper.GetWrappedType(typeof(DeclarationExpressionSyntaxWrapper));
26+
TypeAccessor = LightupHelpers.CreateSyntaxPropertyAccessor<ExpressionSyntax, TypeSyntax>(WrappedType, nameof(Type));
27+
DesignationAccessor = LightupHelpers.CreateSyntaxPropertyAccessor<ExpressionSyntax, CSharpSyntaxNode>(WrappedType, nameof(Designation));
28+
WithTypeAccessor = LightupHelpers.CreateSyntaxWithPropertyAccessor<ExpressionSyntax, TypeSyntax>(WrappedType, nameof(Type));
29+
WithDesignationAccessor = LightupHelpers.CreateSyntaxWithPropertyAccessor<ExpressionSyntax, CSharpSyntaxNode>(WrappedType, nameof(Designation));
3130
}
3231

3332
private DeclarationExpressionSyntaxWrapper(ExpressionSyntax node)
@@ -62,7 +61,7 @@ public static explicit operator DeclarationExpressionSyntaxWrapper(SyntaxNode no
6261

6362
if (!IsInstance(node))
6463
{
65-
throw new InvalidCastException($"Cannot cast '{node.GetType().FullName}' to '{DeclarationExpressionSyntaxTypeName}'");
64+
throw new InvalidCastException($"Cannot cast '{node.GetType().FullName}' to '{WrappedTypeName}'");
6665
}
6766

6867
return new DeclarationExpressionSyntaxWrapper((ExpressionSyntax)node);
@@ -75,7 +74,7 @@ public static implicit operator ExpressionSyntax(DeclarationExpressionSyntaxWrap
7574

7675
public static bool IsInstance(SyntaxNode node)
7776
{
78-
return node != null && LightupHelpers.CanWrapNode(node, DeclarationExpressionSyntaxType);
77+
return node != null && LightupHelpers.CanWrapNode(node, WrappedType);
7978
}
8079

8180
public DeclarationExpressionSyntaxWrapper WithType(TypeSyntax type)

0 commit comments

Comments
 (0)