Skip to content

Commit 68bc8c8

Browse files
committed
Use IOperation APIs for SA1129 when supported
1 parent b63065b commit 68bc8c8

File tree

11 files changed

+562
-47
lines changed

11 files changed

+562
-47
lines changed

StyleCop.Analyzers/StyleCop.Analyzers.Test/ReadabilityRules/SA1129UnitTests.cs

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -91,9 +91,9 @@ public async Task VerifyInvalidValueTypeCreationAsync()
9191
{
9292
public void TestMethod()
9393
{
94-
var v1 = new TestStruct();
94+
var v1 = {|#0:new TestStruct()|};
9595
96-
System.Console.WriteLine(new TestStruct());
96+
System.Console.WriteLine({|#1:new TestStruct()|});
9797
}
9898
9999
private struct TestStruct
@@ -121,8 +121,8 @@ private struct TestStruct
121121

122122
DiagnosticResult[] expected =
123123
{
124-
Diagnostic().WithLocation(5, 18),
125-
Diagnostic().WithLocation(7, 34),
124+
Diagnostic().WithLocation(0),
125+
Diagnostic().WithLocation(1),
126126
};
127127

128128
await VerifyCSharpFixAsync(testCode, expected, fixedTestCode, CancellationToken.None).ConfigureAwait(false);
@@ -139,11 +139,11 @@ public async Task VerifyTriviaPreservationAsync()
139139
{
140140
public void TestMethod()
141141
{
142-
var v1 = /* c1 */ new TestStruct(); // c2
142+
var v1 = /* c1 */ {|#0:new TestStruct()|}; // c2
143143
144144
var v2 =
145145
#if true
146-
new TestStruct();
146+
{|#1:new TestStruct()|};
147147
#else
148148
new TestStruct() { TestProperty = 3 };
149149
#endif
@@ -179,8 +179,8 @@ private struct TestStruct
179179

180180
DiagnosticResult[] expected =
181181
{
182-
Diagnostic().WithLocation(5, 27),
183-
Diagnostic().WithLocation(9, 13),
182+
Diagnostic().WithLocation(0),
183+
Diagnostic().WithLocation(1),
184184
};
185185

186186
await VerifyCSharpFixAsync(testCode, expected, fixedTestCode, CancellationToken.None).ConfigureAwait(false);
@@ -198,7 +198,7 @@ public async Task VerifyGenericsTypeCreationAsync()
198198
public T TestMethod1<T>()
199199
where T : struct
200200
{
201-
return new T();
201+
return {|#0:new T()|};
202202
}
203203
204204
public T TestMethod2<T>()
@@ -227,7 +227,7 @@ public T TestMethod2<T>()
227227

228228
DiagnosticResult[] expected =
229229
{
230-
Diagnostic().WithLocation(6, 16),
230+
Diagnostic().WithLocation(0),
231231
};
232232

233233
await VerifyCSharpFixAsync(testCode, expected, fixedTestCode, CancellationToken.None).ConfigureAwait(false);
@@ -451,7 +451,7 @@ public async Task VerifyEnumMemberReplacementBehaviorAsync(string declarationBod
451451
{{
452452
public void TestMethod()
453453
{{
454-
var v1 = new MyEnum();
454+
var v1 = {{|#0:new MyEnum()|}};
455455
}}
456456
457457
private enum MyEnum {{ {declarationBody} }}
@@ -469,7 +469,7 @@ private enum MyEnum {{ {declarationBody} }}
469469

470470
DiagnosticResult[] expected =
471471
{
472-
Diagnostic().WithLocation(5, 18),
472+
Diagnostic().WithLocation(0),
473473
};
474474

475475
await VerifyCSharpFixAsync(testCode, expected, fixedTestCode, CancellationToken.None).ConfigureAwait(false);
@@ -492,7 +492,7 @@ public async Task VerifyEnumMemberDefaultBehaviorAsync(string declarationBody)
492492
{{
493493
public void TestMethod()
494494
{{
495-
var v1 = new MyEnum();
495+
var v1 = {{|#0:new MyEnum()|}};
496496
}}
497497
498498
private enum MyEnum {{ {declarationBody} }}
@@ -510,7 +510,7 @@ private enum MyEnum {{ {declarationBody} }}
510510

511511
DiagnosticResult[] expected =
512512
{
513-
Diagnostic().WithLocation(5, 18),
513+
Diagnostic().WithLocation(0),
514514
};
515515

516516
await VerifyCSharpFixAsync(testCode, expected, fixedTestCode, CancellationToken.None).ConfigureAwait(false);
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
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 System;
7+
using Microsoft.CodeAnalysis;
8+
9+
internal readonly struct IArgumentOperationWrapper : IOperationWrapper
10+
{
11+
internal const string WrappedTypeName = "Microsoft.CodeAnalysis.Operations.IArgumentOperation";
12+
private static readonly Type WrappedType;
13+
14+
private readonly IOperation operation;
15+
16+
static IArgumentOperationWrapper()
17+
{
18+
WrappedType = WrapperHelper.GetWrappedType(typeof(IObjectCreationOperationWrapper));
19+
}
20+
21+
private IArgumentOperationWrapper(IOperation operation)
22+
{
23+
this.operation = operation;
24+
}
25+
26+
public IOperation WrappedOperation => this.operation;
27+
28+
public ITypeSymbol Type => this.WrappedOperation.Type;
29+
30+
public static IArgumentOperationWrapper FromOperation(IOperation operation)
31+
{
32+
if (operation == null)
33+
{
34+
return default;
35+
}
36+
37+
if (!IsInstance(operation))
38+
{
39+
throw new InvalidCastException($"Cannot cast '{operation.GetType().FullName}' to '{WrappedTypeName}'");
40+
}
41+
42+
return new IArgumentOperationWrapper(operation);
43+
}
44+
45+
public static bool IsInstance(IOperation operation)
46+
{
47+
return operation != null && LightupHelpers.CanWrapOperation(operation, WrappedType);
48+
}
49+
}
50+
}
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
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 System;
7+
using System.Collections.Immutable;
8+
using Microsoft.CodeAnalysis;
9+
10+
internal readonly struct IObjectCreationOperationWrapper : IOperationWrapper
11+
{
12+
internal const string WrappedTypeName = "Microsoft.CodeAnalysis.Operations.IObjectCreationOperation";
13+
private static readonly Type WrappedType;
14+
15+
private static readonly Func<IOperation, IMethodSymbol> ConstructorAccessor;
16+
private static readonly Func<IOperation, IOperation> InitializerAccessor;
17+
private static readonly Func<IOperation, ImmutableArray<IOperation>> ArgumentsAccessor;
18+
19+
private readonly IOperation operation;
20+
21+
static IObjectCreationOperationWrapper()
22+
{
23+
WrappedType = WrapperHelper.GetWrappedType(typeof(IObjectCreationOperationWrapper));
24+
ConstructorAccessor = LightupHelpers.CreateOperationPropertyAccessor<IOperation, IMethodSymbol>(WrappedType, nameof(Constructor));
25+
InitializerAccessor = LightupHelpers.CreateOperationPropertyAccessor<IOperation, IOperation>(WrappedType, nameof(Initializer));
26+
ArgumentsAccessor = LightupHelpers.CreateOperationListPropertyAccessor<IOperation>(WrappedType, nameof(Arguments));
27+
}
28+
29+
private IObjectCreationOperationWrapper(IOperation operation)
30+
{
31+
this.operation = operation;
32+
}
33+
34+
public IOperation WrappedOperation => this.operation;
35+
36+
public ITypeSymbol Type => this.WrappedOperation.Type;
37+
38+
public IMethodSymbol Constructor
39+
{
40+
get
41+
{
42+
return ConstructorAccessor(this.WrappedOperation);
43+
}
44+
}
45+
46+
public IObjectOrCollectionInitializerOperationWrapper Initializer
47+
{
48+
get
49+
{
50+
return IObjectOrCollectionInitializerOperationWrapper.FromOperation(InitializerAccessor(this.WrappedOperation));
51+
}
52+
}
53+
54+
public ImmutableArray<IOperation> Arguments
55+
{
56+
get
57+
{
58+
return ArgumentsAccessor(this.WrappedOperation);
59+
}
60+
}
61+
62+
public static IObjectCreationOperationWrapper FromOperation(IOperation operation)
63+
{
64+
if (operation == null)
65+
{
66+
return default;
67+
}
68+
69+
if (!IsInstance(operation))
70+
{
71+
throw new InvalidCastException($"Cannot cast '{operation.GetType().FullName}' to '{WrappedTypeName}'");
72+
}
73+
74+
return new IObjectCreationOperationWrapper(operation);
75+
}
76+
77+
public static bool IsInstance(IOperation operation)
78+
{
79+
return operation != null && LightupHelpers.CanWrapOperation(operation, WrappedType);
80+
}
81+
}
82+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
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 System;
7+
using System.Collections.Immutable;
8+
using Microsoft.CodeAnalysis;
9+
10+
internal readonly struct IObjectOrCollectionInitializerOperationWrapper : IOperationWrapper
11+
{
12+
internal const string WrappedTypeName = "Microsoft.CodeAnalysis.Operations.IObjectOrCollectionInitializerOperation";
13+
private static readonly Type WrappedType;
14+
15+
private static readonly Func<IOperation, ImmutableArray<IOperation>> InitializersAccessor;
16+
17+
private readonly IOperation operation;
18+
19+
static IObjectOrCollectionInitializerOperationWrapper()
20+
{
21+
WrappedType = WrapperHelper.GetWrappedType(typeof(IObjectOrCollectionInitializerOperationWrapper));
22+
InitializersAccessor = LightupHelpers.CreateOperationPropertyAccessor<IOperation, ImmutableArray<IOperation>>(WrappedType, nameof(Initializers));
23+
}
24+
25+
private IObjectOrCollectionInitializerOperationWrapper(IOperation operation)
26+
{
27+
this.operation = operation;
28+
}
29+
30+
public IOperation WrappedOperation => this.operation;
31+
32+
public ITypeSymbol Type => this.WrappedOperation.Type;
33+
34+
public ImmutableArray<IOperation> Initializers
35+
{
36+
get
37+
{
38+
return InitializersAccessor(this.WrappedOperation);
39+
}
40+
}
41+
42+
public static IObjectOrCollectionInitializerOperationWrapper FromOperation(IOperation operation)
43+
{
44+
if (operation == null)
45+
{
46+
return default;
47+
}
48+
49+
if (!IsInstance(operation))
50+
{
51+
throw new InvalidCastException($"Cannot cast '{operation.GetType().FullName}' to '{WrappedTypeName}'");
52+
}
53+
54+
return new IObjectOrCollectionInitializerOperationWrapper(operation);
55+
}
56+
57+
public static bool IsInstance(IOperation operation)
58+
{
59+
return operation != null && LightupHelpers.CanWrapOperation(operation, WrappedType);
60+
}
61+
}
62+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
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+
#nullable enable
5+
6+
namespace StyleCop.Analyzers.Lightup
7+
{
8+
using Microsoft.CodeAnalysis;
9+
10+
internal interface IOperationWrapper
11+
{
12+
IOperation? WrappedOperation { get; }
13+
14+
////IOperationWrapper Parent { get; }
15+
16+
////OperationKind Kind { get; }
17+
18+
////SyntaxNode Syntax { get; }
19+
20+
ITypeSymbol? Type { get; }
21+
22+
////Optional<object> ConstantValue { get; }
23+
24+
////IEnumerable<IOperationWrapper> Children { get; }
25+
26+
////string Language { get; }
27+
28+
////bool IsImplicit { get; }
29+
30+
////SemanticModel SemanticModel { get; }
31+
}
32+
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
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 System;
7+
using Microsoft.CodeAnalysis;
8+
9+
internal readonly struct ITypeParameterObjectCreationOperationWrapper : IOperationWrapper
10+
{
11+
internal const string WrappedTypeName = "Microsoft.CodeAnalysis.Operations.ITypeParameterObjectCreationOperation";
12+
private static readonly Type WrappedType;
13+
14+
private static readonly Func<IOperation, IOperation> InitializerAccessor;
15+
16+
private readonly IOperation operation;
17+
18+
static ITypeParameterObjectCreationOperationWrapper()
19+
{
20+
WrappedType = WrapperHelper.GetWrappedType(typeof(ITypeParameterObjectCreationOperationWrapper));
21+
InitializerAccessor = LightupHelpers.CreateOperationPropertyAccessor<IOperation, IOperation>(WrappedType, nameof(Initializer));
22+
}
23+
24+
private ITypeParameterObjectCreationOperationWrapper(IOperation operation)
25+
{
26+
this.operation = operation;
27+
}
28+
29+
public IOperation WrappedOperation => this.operation;
30+
31+
public ITypeSymbol Type => this.WrappedOperation.Type;
32+
33+
public IObjectOrCollectionInitializerOperationWrapper Initializer
34+
{
35+
get
36+
{
37+
return IObjectOrCollectionInitializerOperationWrapper.FromOperation(InitializerAccessor(this.WrappedOperation));
38+
}
39+
}
40+
41+
public static ITypeParameterObjectCreationOperationWrapper FromOperation(IOperation operation)
42+
{
43+
if (operation == null)
44+
{
45+
return default;
46+
}
47+
48+
if (!IsInstance(operation))
49+
{
50+
throw new InvalidCastException($"Cannot cast '{operation.GetType().FullName}' to '{WrappedTypeName}'");
51+
}
52+
53+
return new ITypeParameterObjectCreationOperationWrapper(operation);
54+
}
55+
56+
public static bool IsInstance(IOperation operation)
57+
{
58+
return operation != null && LightupHelpers.CanWrapOperation(operation, WrappedType);
59+
}
60+
}
61+
}

0 commit comments

Comments
 (0)