Skip to content

Commit d2a3d2b

Browse files
committed
Merge branch 'master' into feature/Issue3386CastInRange
2 parents 7754e6b + ca7ccd2 commit d2a3d2b

File tree

30 files changed

+424
-102
lines changed

30 files changed

+424
-102
lines changed

StyleCop.Analyzers/Directory.Build.props

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@
1010
</PropertyGroup>
1111

1212
<PropertyGroup>
13-
<LangVersion>9</LangVersion>
14-
<WarningLevel>5</WarningLevel>
13+
<LangVersion>10</LangVersion>
14+
<WarningLevel>99</WarningLevel>
1515
</PropertyGroup>
1616

1717
<PropertyGroup Condition="'$(BuildingInsideVisualStudio)' != 'true'">
@@ -47,12 +47,12 @@
4747
<PackageReference Include="DotNetAnalyzers.DocumentationAnalyzers" Version="1.0.0-beta.46" PrivateAssets="all" />
4848
<PackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.304" PrivateAssets="all" />
4949
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.2" PrivateAssets="all" />
50-
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.CodeStyle" Version="3.8.0" PrivateAssets="all" />
50+
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.CodeStyle" Version="4.0.1" PrivateAssets="all" />
5151
</ItemGroup>
5252

5353
<!-- C# Compiler -->
5454
<ItemGroup>
55-
<PackageReference Include="Microsoft.Net.Compilers.Toolset" Version="3.8.0" PrivateAssets="all" />
55+
<PackageReference Include="Microsoft.Net.Compilers.Toolset" Version="4.0.1" PrivateAssets="all" />
5656
</ItemGroup>
5757

5858
<!-- Public API -->

StyleCop.Analyzers/StyleCop.Analyzers.CodeGeneration/OperationLightupGenerator.cs

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,16 @@ namespace StyleCop.Analyzers.CodeGeneration
1919
using Microsoft.CodeAnalysis.Text;
2020

2121
[Generator]
22-
internal sealed class OperationLightupGenerator : ISourceGenerator
22+
internal sealed class OperationLightupGenerator : IIncrementalGenerator
2323
{
24-
public void Initialize(GeneratorInitializationContext context)
24+
public void Initialize(IncrementalGeneratorInitializationContext context)
2525
{
26+
var operationInterfacesFiles = context.AdditionalTextsProvider.Where(static x => Path.GetFileName(x.Path) == "OperationInterfaces.xml");
27+
context.RegisterSourceOutput(operationInterfacesFiles, this.Execute);
2628
}
2729

28-
public void Execute(GeneratorExecutionContext context)
30+
private void Execute(SourceProductionContext context, AdditionalText operationInterfacesFile)
2931
{
30-
var operationInterfacesFile = context.AdditionalFiles.Single(x => Path.GetFileName(x.Path) == "OperationInterfaces.xml");
3132
var operationInterfacesText = operationInterfacesFile.GetText(context.CancellationToken);
3233
if (operationInterfacesText is null)
3334
{
@@ -38,7 +39,7 @@ public void Execute(GeneratorExecutionContext context)
3839
this.GenerateOperationInterfaces(in context, operationInterfaces);
3940
}
4041

41-
private void GenerateOperationInterfaces(in GeneratorExecutionContext context, XDocument operationInterfaces)
42+
private void GenerateOperationInterfaces(in SourceProductionContext context, XDocument operationInterfaces)
4243
{
4344
var tree = operationInterfaces.XPathSelectElement("/Tree");
4445
if (tree is null)
@@ -56,7 +57,7 @@ private void GenerateOperationInterfaces(in GeneratorExecutionContext context, X
5657
this.GenerateOperationKindEx(in context, documentData.Interfaces.Values.ToImmutableArray());
5758
}
5859

59-
private void GenerateOperationInterface(in GeneratorExecutionContext context, InterfaceData node)
60+
private void GenerateOperationInterface(in SourceProductionContext context, InterfaceData node)
6061
{
6162
var members = SyntaxFactory.List<MemberDeclarationSyntax>();
6263

@@ -69,7 +70,7 @@ private void GenerateOperationInterface(in GeneratorExecutionContext context, In
6970
variables: SyntaxFactory.SingletonSeparatedList(SyntaxFactory.VariableDeclarator(
7071
identifier: SyntaxFactory.Identifier("WrappedTypeName"),
7172
argumentList: null,
72-
initializer: SyntaxFactory.EqualsValueClause(SyntaxFactory.LiteralExpression(SyntaxKind.StringLiteralExpression, SyntaxFactory.Literal("Microsoft.CodeAnalysis.Operations." + node.InterfaceName))))))));
73+
initializer: SyntaxFactory.EqualsValueClause(SyntaxFactory.LiteralExpression(SyntaxKind.StringLiteralExpression, SyntaxFactory.Literal($"Microsoft.CodeAnalysis.{node.Namespace}.{node.InterfaceName}"))))))));
7374

7475
// private static readonly Type WrappedType;
7576
members = members.Add(SyntaxFactory.FieldDeclaration(
@@ -581,7 +582,7 @@ private void GenerateOperationInterface(in GeneratorExecutionContext context, In
581582
context.AddSource(node.WrapperName + ".g.cs", SourceText.From(wrapperNamespace.ToFullString(), Encoding.UTF8));
582583
}
583584

584-
private void GenerateOperationWrapperHelper(in GeneratorExecutionContext context, ImmutableArray<InterfaceData> wrapperTypes)
585+
private void GenerateOperationWrapperHelper(in SourceProductionContext context, ImmutableArray<InterfaceData> wrapperTypes)
585586
{
586587
// private static readonly ImmutableDictionary<Type, Type> WrappedTypes;
587588
var wrappedTypes = SyntaxFactory.FieldDeclaration(
@@ -789,7 +790,7 @@ private void GenerateOperationWrapperHelper(in GeneratorExecutionContext context
789790
context.AddSource("OperationWrapperHelper.g.cs", SourceText.From(wrapperNamespace.ToFullString(), Encoding.UTF8));
790791
}
791792

792-
private void GenerateOperationKindEx(in GeneratorExecutionContext context, ImmutableArray<InterfaceData> wrapperTypes)
793+
private void GenerateOperationKindEx(in SourceProductionContext context, ImmutableArray<InterfaceData> wrapperTypes)
793794
{
794795
var operationKinds = wrapperTypes
795796
.SelectMany(type => type.OperationKinds)
@@ -988,6 +989,7 @@ public InterfaceData(DocumentData documentData, XElement node, ImmutableArray<(s
988989

989990
this.OperationKinds = operationKinds;
990991
this.InterfaceName = node.Attribute("Name").Value;
992+
this.Namespace = node.Attribute("Namespace")?.Value ?? "Operations";
991993
this.Name = this.InterfaceName.Substring("I".Length, this.InterfaceName.Length - "I".Length - "Operation".Length);
992994
this.WrapperName = this.InterfaceName + "Wrapper";
993995
this.BaseInterfaceName = node.Attribute("Base").Value;
@@ -999,6 +1001,8 @@ public InterfaceData(DocumentData documentData, XElement node, ImmutableArray<(s
9991001

10001002
public string InterfaceName { get; }
10011003

1004+
public string Namespace { get; }
1005+
10021006
public string Name { get; }
10031007

10041008
public string WrapperName { get; }

StyleCop.Analyzers/StyleCop.Analyzers.CodeGeneration/StyleCop.Analyzers.CodeGeneration.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
</PropertyGroup>
1717

1818
<ItemGroup>
19-
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="3.8.0" />
19+
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.0.1" />
2020
<PackageReference Include="TunnelVisionLabs.ReferenceAssemblyAnnotator" Version="1.0.0-alpha.160" PrivateAssets="all" />
2121
<PackageDownload Include="Microsoft.NETCore.App.Ref" Version="[3.1.0]" />
2222
</ItemGroup>

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

Lines changed: 77 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ namespace StyleCop.Analyzers.CodeGeneration
1919
using Microsoft.CodeAnalysis.Text;
2020

2121
[Generator]
22-
internal sealed class SyntaxLightupGenerator : ISourceGenerator
22+
internal sealed class SyntaxLightupGenerator : IIncrementalGenerator
2323
{
2424
private enum NodeKind
2525
{
@@ -28,33 +28,37 @@ private enum NodeKind
2828
Concrete,
2929
}
3030

31-
public void Initialize(GeneratorInitializationContext context)
31+
public void Initialize(IncrementalGeneratorInitializationContext context)
3232
{
33+
var compilation = context.CompilationProvider;
34+
var syntaxFiles = context.AdditionalTextsProvider.Where(static x => Path.GetFileName(x.Path) == "Syntax.xml");
35+
context.RegisterSourceOutput(
36+
syntaxFiles.Combine(compilation),
37+
(context, value) => this.Execute(in context, value.Right, value.Left));
3338
}
3439

35-
public void Execute(GeneratorExecutionContext context)
40+
private void Execute(in SourceProductionContext context, Compilation compilation, AdditionalText syntaxFile)
3641
{
37-
var syntaxFile = context.AdditionalFiles.Single(x => Path.GetFileName(x.Path) == "Syntax.xml");
3842
var syntaxText = syntaxFile.GetText(context.CancellationToken);
3943
if (syntaxText is null)
4044
{
4145
throw new InvalidOperationException("Failed to read Syntax.xml");
4246
}
4347

44-
var syntaxData = new SyntaxData(in context, XDocument.Parse(syntaxText.ToString()));
48+
var syntaxData = new SyntaxData(compilation, XDocument.Parse(syntaxText.ToString()));
4549
this.GenerateSyntaxWrappers(in context, syntaxData);
4650
this.GenerateSyntaxWrapperHelper(in context, syntaxData.Nodes);
4751
}
4852

49-
private void GenerateSyntaxWrappers(in GeneratorExecutionContext context, SyntaxData syntaxData)
53+
private void GenerateSyntaxWrappers(in SourceProductionContext context, SyntaxData syntaxData)
5054
{
5155
foreach (var node in syntaxData.Nodes)
5256
{
5357
this.GenerateSyntaxWrapper(in context, syntaxData, node);
5458
}
5559
}
5660

57-
private void GenerateSyntaxWrapper(in GeneratorExecutionContext context, SyntaxData syntaxData, NodeData nodeData)
61+
private void GenerateSyntaxWrapper(in SourceProductionContext context, SyntaxData syntaxData, NodeData nodeData)
5862
{
5963
if (nodeData.WrapperName is null)
6064
{
@@ -806,7 +810,7 @@ private void GenerateSyntaxWrapper(in GeneratorExecutionContext context, SyntaxD
806810
context.AddSource(nodeData.WrapperName + ".g.cs", SourceText.From(wrapperNamespace.ToFullString(), Encoding.UTF8));
807811
}
808812

809-
private void GenerateSyntaxWrapperHelper(in GeneratorExecutionContext context, ImmutableArray<NodeData> wrapperTypes)
813+
private void GenerateSyntaxWrapperHelper(in SourceProductionContext context, ImmutableArray<NodeData> wrapperTypes)
810814
{
811815
// private static readonly ImmutableDictionary<Type, Type> WrappedTypes;
812816
var wrappedTypes = SyntaxFactory.FieldDeclaration(
@@ -982,6 +986,65 @@ private void GenerateSyntaxWrapperHelper(in GeneratorExecutionContext context, I
982986
continue;
983987
}
984988

989+
if (node.Name == nameof(BaseNamespaceDeclarationSyntax))
990+
{
991+
// Prior to C# 10, NamespaceDeclarationSyntax was the base type for all namespace declarations.
992+
// If the BaseNamespaceDeclarationSyntax type isn't found at runtime, we fall back
993+
// to using this type instead.
994+
//
995+
// var baseNamespaceDeclarationSyntaxType = csharpCodeAnalysisAssembly.GetType(BaseNamespaceDeclarationSyntaxWrapper.WrappedTypeName)
996+
// ?? csharpCodeAnalysisAssembly.GetType(BaseNamespaceDeclarationSyntaxWrapper.WrappedTypeName);
997+
LocalDeclarationStatementSyntax localStatement =
998+
SyntaxFactory.LocalDeclarationStatement(SyntaxFactory.VariableDeclaration(
999+
type: SyntaxFactory.IdentifierName("var"),
1000+
variables: SyntaxFactory.SingletonSeparatedList(SyntaxFactory.VariableDeclarator(
1001+
identifier: SyntaxFactory.Identifier("baseNamespaceDeclarationSyntaxType"),
1002+
argumentList: null,
1003+
initializer: SyntaxFactory.EqualsValueClause(
1004+
SyntaxFactory.BinaryExpression(
1005+
SyntaxKind.CoalesceExpression,
1006+
left: SyntaxFactory.InvocationExpression(
1007+
expression: SyntaxFactory.MemberAccessExpression(
1008+
SyntaxKind.SimpleMemberAccessExpression,
1009+
expression: SyntaxFactory.IdentifierName("csharpCodeAnalysisAssembly"),
1010+
name: SyntaxFactory.IdentifierName("GetType")),
1011+
argumentList: SyntaxFactory.ArgumentList(SyntaxFactory.SingletonSeparatedList(SyntaxFactory.Argument(
1012+
SyntaxFactory.MemberAccessExpression(
1013+
SyntaxKind.SimpleMemberAccessExpression,
1014+
expression: SyntaxFactory.IdentifierName(node.WrapperName),
1015+
name: SyntaxFactory.IdentifierName("WrappedTypeName")))))),
1016+
right: SyntaxFactory.InvocationExpression(
1017+
expression: SyntaxFactory.MemberAccessExpression(
1018+
SyntaxKind.SimpleMemberAccessExpression,
1019+
expression: SyntaxFactory.IdentifierName("csharpCodeAnalysisAssembly"),
1020+
name: SyntaxFactory.IdentifierName("GetType")),
1021+
argumentList: SyntaxFactory.ArgumentList(SyntaxFactory.SingletonSeparatedList(SyntaxFactory.Argument(
1022+
SyntaxFactory.MemberAccessExpression(
1023+
SyntaxKind.SimpleMemberAccessExpression,
1024+
expression: SyntaxFactory.IdentifierName(node.WrapperName),
1025+
name: SyntaxFactory.IdentifierName("FallbackWrappedTypeName"))))))))))));
1026+
1027+
// This is the first line of the statements that initialize 'builder', so start it with a blank line
1028+
staticCtorStatements = staticCtorStatements.Add(localStatement.WithLeadingBlankLine());
1029+
1030+
// builder.Add(typeof(BaseNamespaceDeclarationSyntaxWrapper), baseNamespaceDeclarationSyntaxType);
1031+
staticCtorStatements = staticCtorStatements.Add(SyntaxFactory.ExpressionStatement(
1032+
SyntaxFactory.InvocationExpression(
1033+
expression: SyntaxFactory.MemberAccessExpression(
1034+
SyntaxKind.SimpleMemberAccessExpression,
1035+
expression: SyntaxFactory.IdentifierName("builder"),
1036+
name: SyntaxFactory.IdentifierName("Add")),
1037+
argumentList: SyntaxFactory.ArgumentList(
1038+
SyntaxFactory.SeparatedList(
1039+
new[]
1040+
{
1041+
SyntaxFactory.Argument(SyntaxFactory.TypeOfExpression(SyntaxFactory.IdentifierName(node.WrapperName))),
1042+
SyntaxFactory.Argument(SyntaxFactory.IdentifierName("baseNamespaceDeclarationSyntaxType")),
1043+
})))));
1044+
1045+
continue;
1046+
}
1047+
9851048
// builder.Add(typeof(ConstantPatternSyntaxWrapper), csharpCodeAnalysisAssembly.GetType(ConstantPatternSyntaxWrapper.WrappedTypeName));
9861049
staticCtorStatements = staticCtorStatements.Add(SyntaxFactory.ExpressionStatement(
9871050
SyntaxFactory.InvocationExpression(
@@ -1138,12 +1201,12 @@ private sealed class SyntaxData
11381201
{
11391202
private readonly Dictionary<string, NodeData> nameToNode;
11401203

1141-
public SyntaxData(in GeneratorExecutionContext context, XDocument document)
1204+
public SyntaxData(Compilation compilation, XDocument document)
11421205
{
11431206
var nodesBuilder = ImmutableArray.CreateBuilder<NodeData>();
11441207
foreach (var element in document.XPathSelectElement("/Tree[@Root='SyntaxNode']").XPathSelectElements("PredefinedNode|AbstractNode|Node"))
11451208
{
1146-
nodesBuilder.Add(new NodeData(in context, element));
1209+
nodesBuilder.Add(new NodeData(compilation, element));
11471210
}
11481211

11491212
this.Nodes = nodesBuilder.ToImmutable();
@@ -1180,7 +1243,7 @@ public SyntaxData(in GeneratorExecutionContext context, XDocument document)
11801243

11811244
private sealed class NodeData
11821245
{
1183-
public NodeData(in GeneratorExecutionContext context, XElement element)
1246+
public NodeData(Compilation compilation, XElement element)
11841247
{
11851248
this.Kind = element.Name.LocalName switch
11861249
{
@@ -1192,9 +1255,9 @@ public NodeData(in GeneratorExecutionContext context, XElement element)
11921255

11931256
this.Name = element.Attribute("Name").Value;
11941257

1195-
this.ExistingType = context.Compilation.GetTypeByMetadataName($"Microsoft.CodeAnalysis.CSharp.Syntax.{this.Name}")
1196-
?? context.Compilation.GetTypeByMetadataName($"Microsoft.CodeAnalysis.CSharp.{this.Name}")
1197-
?? context.Compilation.GetTypeByMetadataName($"Microsoft.CodeAnalysis.{this.Name}");
1258+
this.ExistingType = compilation.GetTypeByMetadataName($"Microsoft.CodeAnalysis.CSharp.Syntax.{this.Name}")
1259+
?? compilation.GetTypeByMetadataName($"Microsoft.CodeAnalysis.CSharp.{this.Name}")
1260+
?? compilation.GetTypeByMetadataName($"Microsoft.CodeAnalysis.{this.Name}");
11981261
if (this.ExistingType?.DeclaredAccessibility == Accessibility.Public)
11991262
{
12001263
this.WrapperName = null;

StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/ReadabilityRules/SA1135CSharp10UnitTests.cs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,53 @@
33

44
namespace StyleCop.Analyzers.Test.CSharp10.ReadabilityRules
55
{
6+
using System.Threading;
7+
using System.Threading.Tasks;
8+
using Microsoft.CodeAnalysis.Testing;
69
using StyleCop.Analyzers.Test.CSharp9.ReadabilityRules;
10+
using Xunit;
11+
using static StyleCop.Analyzers.Test.Verifiers.StyleCopCodeFixVerifier<
12+
StyleCop.Analyzers.ReadabilityRules.SA1135UsingDirectivesMustBeQualified,
13+
StyleCop.Analyzers.ReadabilityRules.SA1135CodeFixProvider>;
714

815
public class SA1135CSharp10UnitTests : SA1135CSharp9UnitTests
916
{
17+
[Fact]
18+
[WorkItem(3415, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3415")]
19+
public async Task TestFileScopedNamespaceAsync()
20+
{
21+
var testCode = @"
22+
namespace TestNamespace
23+
{
24+
using KeyValue = System.Collections.Generic.KeyValuePair<string, object?>;
25+
}
26+
";
27+
await VerifyCSharpDiagnosticAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
28+
await new CSharpTest
29+
{
30+
TestState =
31+
{
32+
Sources =
33+
{
34+
@"namespace A.B.C { }",
35+
@"namespace A.B.D;
36+
37+
[|using C;|]
38+
",
39+
},
40+
},
41+
FixedState =
42+
{
43+
Sources =
44+
{
45+
@"namespace A.B.C { }",
46+
@"namespace A.B.D;
47+
48+
using A.B.C;
49+
",
50+
},
51+
},
52+
}.RunAsync(CancellationToken.None).ConfigureAwait(false);
53+
}
1054
}
1155
}

0 commit comments

Comments
 (0)