Skip to content

Commit f851c85

Browse files
committed
Fix fallback support for BaseObjectCreationExpressionSyntaxWrapper
See #3258
1 parent 57bc54d commit f851c85

File tree

4 files changed

+86
-12
lines changed

4 files changed

+86
-12
lines changed

StyleCop.Analyzers/StyleCop.Analyzers.CodeGeneration/SyntaxLightupGenerator.cs

Lines changed: 61 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -861,7 +861,6 @@ private void GenerateSyntaxWrapperHelper(in GeneratorExecutionContext context, I
861861
SyntaxFactory.IdentifierName("Type"),
862862
})))))))))));
863863

864-
bool first = true;
865864
foreach (var node in wrapperTypes.OrderBy(node => node.Name, StringComparer.OrdinalIgnoreCase))
866865
{
867866
if (node.WrapperName is null)
@@ -924,8 +923,67 @@ private void GenerateSyntaxWrapperHelper(in GeneratorExecutionContext context, I
924923
continue;
925924
}
926925

926+
if (node.Name == nameof(BaseObjectCreationExpressionSyntax))
927+
{
928+
// Prior to C# 9, ObjectCreationExpressionSyntax was the base type for all object creation
929+
// statements. If the BaseObjectCreationExpressionSyntax type isn't found at runtime, we fall back
930+
// to using this type instead.
931+
//
932+
// var objectCreationExpressionSyntaxType = csharpCodeAnalysisAssembly.GetType(BaseObjectCreationExpressionSyntaxWrapper.WrappedTypeName)
933+
// ?? csharpCodeAnalysisAssembly.GetType(BaseObjectCreationExpressionSyntaxWrapper.FallbackWrappedTypeName);
934+
LocalDeclarationStatementSyntax localStatement =
935+
SyntaxFactory.LocalDeclarationStatement(SyntaxFactory.VariableDeclaration(
936+
type: SyntaxFactory.IdentifierName("var"),
937+
variables: SyntaxFactory.SingletonSeparatedList(SyntaxFactory.VariableDeclarator(
938+
identifier: SyntaxFactory.Identifier("objectCreationExpressionSyntaxType"),
939+
argumentList: null,
940+
initializer: SyntaxFactory.EqualsValueClause(
941+
SyntaxFactory.BinaryExpression(
942+
SyntaxKind.CoalesceExpression,
943+
left: SyntaxFactory.InvocationExpression(
944+
expression: SyntaxFactory.MemberAccessExpression(
945+
SyntaxKind.SimpleMemberAccessExpression,
946+
expression: SyntaxFactory.IdentifierName("csharpCodeAnalysisAssembly"),
947+
name: SyntaxFactory.IdentifierName("GetType")),
948+
argumentList: SyntaxFactory.ArgumentList(SyntaxFactory.SingletonSeparatedList(SyntaxFactory.Argument(
949+
SyntaxFactory.MemberAccessExpression(
950+
SyntaxKind.SimpleMemberAccessExpression,
951+
expression: SyntaxFactory.IdentifierName(node.WrapperName),
952+
name: SyntaxFactory.IdentifierName("WrappedTypeName")))))),
953+
right: SyntaxFactory.InvocationExpression(
954+
expression: SyntaxFactory.MemberAccessExpression(
955+
SyntaxKind.SimpleMemberAccessExpression,
956+
expression: SyntaxFactory.IdentifierName("csharpCodeAnalysisAssembly"),
957+
name: SyntaxFactory.IdentifierName("GetType")),
958+
argumentList: SyntaxFactory.ArgumentList(SyntaxFactory.SingletonSeparatedList(SyntaxFactory.Argument(
959+
SyntaxFactory.MemberAccessExpression(
960+
SyntaxKind.SimpleMemberAccessExpression,
961+
expression: SyntaxFactory.IdentifierName(node.WrapperName),
962+
name: SyntaxFactory.IdentifierName("FallbackWrappedTypeName"))))))))))));
963+
964+
// This is the first line of the statements that initialize 'builder', so start it with a blank line
965+
staticCtorStatements = staticCtorStatements.Add(localStatement.WithLeadingBlankLine());
966+
967+
// builder.Add(typeof(BaseObjectCreationExpressionSyntaxWrapper), objectCreationExpressionSyntaxType);
968+
staticCtorStatements = staticCtorStatements.Add(SyntaxFactory.ExpressionStatement(
969+
SyntaxFactory.InvocationExpression(
970+
expression: SyntaxFactory.MemberAccessExpression(
971+
SyntaxKind.SimpleMemberAccessExpression,
972+
expression: SyntaxFactory.IdentifierName("builder"),
973+
name: SyntaxFactory.IdentifierName("Add")),
974+
argumentList: SyntaxFactory.ArgumentList(
975+
SyntaxFactory.SeparatedList(
976+
new[]
977+
{
978+
SyntaxFactory.Argument(SyntaxFactory.TypeOfExpression(SyntaxFactory.IdentifierName(node.WrapperName))),
979+
SyntaxFactory.Argument(SyntaxFactory.IdentifierName("objectCreationExpressionSyntaxType")),
980+
})))));
981+
982+
continue;
983+
}
984+
927985
// builder.Add(typeof(ConstantPatternSyntaxWrapper), csharpCodeAnalysisAssembly.GetType(ConstantPatternSyntaxWrapper.WrappedTypeName));
928-
ExpressionStatementSyntax statement = SyntaxFactory.ExpressionStatement(
986+
staticCtorStatements = staticCtorStatements.Add(SyntaxFactory.ExpressionStatement(
929987
SyntaxFactory.InvocationExpression(
930988
expression: SyntaxFactory.MemberAccessExpression(
931989
SyntaxKind.SimpleMemberAccessExpression,
@@ -947,15 +1005,7 @@ private void GenerateSyntaxWrapperHelper(in GeneratorExecutionContext context, I
9471005
SyntaxKind.SimpleMemberAccessExpression,
9481006
expression: SyntaxFactory.IdentifierName(node.WrapperName),
9491007
name: SyntaxFactory.IdentifierName("WrappedTypeName"))))))),
950-
}))));
951-
952-
if (first)
953-
{
954-
statement = statement.WithLeadingBlankLine();
955-
first = false;
956-
}
957-
958-
staticCtorStatements = staticCtorStatements.Add(statement);
1008+
})))));
9591009
}
9601010

9611011
// WrappedTypes = builder.ToImmutable();

StyleCop.Analyzers/StyleCop.Analyzers.Test/Lightup/SyntaxWrapperHelperTests.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,12 @@ public void VerifyThatWrapperClassIsPresent(Type wrapperType)
4444
Assert.False(LightupHelpers.SupportsCSharp7);
4545
Assert.Same(typeof(ForEachStatementSyntax), SyntaxWrapperHelper.GetWrappedType(wrapperType));
4646
}
47+
else if (wrapperType == typeof(BaseObjectCreationExpressionSyntaxWrapper))
48+
{
49+
// Special case for C# 6-8 analysis compatibility
50+
Assert.False(LightupHelpers.SupportsCSharp9);
51+
Assert.Same(typeof(ObjectCreationExpressionSyntax), SyntaxWrapperHelper.GetWrappedType(wrapperType));
52+
}
4753
else
4854
{
4955
Assert.Null(SyntaxWrapperHelper.GetWrappedType(wrapperType));

StyleCop.Analyzers/StyleCop.Analyzers/Lightup/.generated/StyleCop.Analyzers.CodeGeneration/StyleCop.Analyzers.CodeGeneration.SyntaxLightupGenerator/SyntaxWrapperHelper.g.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ static SyntaxWrapperHelper()
1818
var csharpCodeAnalysisAssembly = typeof(CSharpSyntaxNode).GetTypeInfo().Assembly;
1919
var builder = ImmutableDictionary.CreateBuilder<Type, Type>();
2020

21-
builder.Add(typeof(BaseObjectCreationExpressionSyntaxWrapper), csharpCodeAnalysisAssembly.GetType(BaseObjectCreationExpressionSyntaxWrapper.WrappedTypeName));
21+
var objectCreationExpressionSyntaxType = csharpCodeAnalysisAssembly.GetType(BaseObjectCreationExpressionSyntaxWrapper.WrappedTypeName) ?? csharpCodeAnalysisAssembly.GetType(BaseObjectCreationExpressionSyntaxWrapper.FallbackWrappedTypeName);
22+
builder.Add(typeof(BaseObjectCreationExpressionSyntaxWrapper), objectCreationExpressionSyntaxType);
2223
builder.Add(typeof(BaseParameterSyntaxWrapper), csharpCodeAnalysisAssembly.GetType(BaseParameterSyntaxWrapper.WrappedTypeName));
2324
builder.Add(typeof(BinaryPatternSyntaxWrapper), csharpCodeAnalysisAssembly.GetType(BinaryPatternSyntaxWrapper.WrappedTypeName));
2425
builder.Add(typeof(CasePatternSwitchLabelSyntaxWrapper), csharpCodeAnalysisAssembly.GetType(CasePatternSwitchLabelSyntaxWrapper.WrappedTypeName));
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Copyright (c) Tunnel Vision Laboratories, LLC. All Rights Reserved.
2+
// Licensed under the MIT License. See LICENSE in the project root for license information.
3+
4+
namespace StyleCop.Analyzers.Lightup
5+
{
6+
using Microsoft.CodeAnalysis.CSharp.Syntax;
7+
8+
internal partial struct BaseObjectCreationExpressionSyntaxWrapper : ISyntaxWrapper<ExpressionSyntax>
9+
{
10+
internal const string FallbackWrappedTypeName = "Microsoft.CodeAnalysis.CSharp.Syntax.ObjectCreationExpressionSyntax";
11+
12+
public static implicit operator BaseObjectCreationExpressionSyntaxWrapper(ObjectCreationExpressionSyntax node)
13+
{
14+
return new BaseObjectCreationExpressionSyntaxWrapper(node);
15+
}
16+
}
17+
}

0 commit comments

Comments
 (0)