-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Implement AG0009 * Refactoring in code review
- Loading branch information
1 parent
71e23b7
commit a484993
Showing
7 changed files
with
232 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
using System.Threading.Tasks; | ||
using Agoda.Analyzers.AgodaCustom; | ||
using Agoda.Analyzers.Test.Helpers; | ||
using Microsoft.AspNetCore.Http; | ||
using Microsoft.CodeAnalysis.Diagnostics; | ||
using NUnit.Framework; | ||
|
||
namespace Agoda.Analyzers.Test.AgodaCustom | ||
{ | ||
class AG0009UnitTests : DiagnosticVerifier | ||
{ | ||
protected override DiagnosticAnalyzer DiagnosticAnalyzer => new AG0009IHttpContextAccessorCannotBePassedAsMethodArgument(); | ||
|
||
protected override string DiagnosticId => AG0009IHttpContextAccessorCannotBePassedAsMethodArgument.DIAGNOSTIC_ID; | ||
|
||
[Test] | ||
public async Task TestIHttpContextAccessorAsArgument() | ||
{ | ||
var code = new CodeDescriptor | ||
{ | ||
References = new[] {typeof(IHttpContextAccessor).Assembly, typeof(HttpContextAccessor).Assembly}, | ||
Code = @" | ||
using Microsoft.AspNetCore.Http; | ||
interface ISomething | ||
{ | ||
void SomeMethod(IHttpContextAccessor c, string sampleString); // ugly interface method | ||
void SomeMethod(HttpContextAccessor c, string sampleString); // ugly interface method | ||
} | ||
class TestClass : ISomething | ||
{ | ||
public void SomeMethod(IHttpContextAccessor context, string sampleString) | ||
{ | ||
// this method is ugly | ||
} | ||
public void SomeMethod(HttpContextAccessor context, string sampleString) | ||
{ | ||
//this method is ugly | ||
} | ||
public TestClass(Microsoft.AspNetCore.Http.IHttpContextAccessor context) | ||
{ | ||
// this constructor is uglier | ||
} | ||
public TestClass(Microsoft.AspNetCore.Http.HttpContextAccessor context) | ||
{ | ||
// this constructor is uglier | ||
} | ||
}" | ||
}; | ||
|
||
var expected = new[] | ||
{ | ||
new DiagnosticLocation(6, 21), | ||
new DiagnosticLocation(7, 21), | ||
new DiagnosticLocation(12, 28), | ||
new DiagnosticLocation(17, 28), | ||
new DiagnosticLocation(22, 23), | ||
new DiagnosticLocation(27, 22) | ||
}; | ||
HttpContextAccessor a; | ||
await VerifyDiagnosticsAsync(code, expected); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
60 changes: 60 additions & 0 deletions
60
src/Agoda.Analyzers/AgodaCustom/AG0009IHttpContextAccessorCannotBePassedAsMethodArgument.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
using System; | ||
using System.Collections.Immutable; | ||
using Agoda.Analyzers.Helpers; | ||
using Microsoft.CodeAnalysis; | ||
using Microsoft.CodeAnalysis.CSharp; | ||
using Microsoft.CodeAnalysis.CSharp.Syntax; | ||
using Microsoft.CodeAnalysis.Diagnostics; | ||
|
||
namespace Agoda.Analyzers.AgodaCustom | ||
{ | ||
[DiagnosticAnalyzer(LanguageNames.CSharp)] | ||
public class AG0009IHttpContextAccessorCannotBePassedAsMethodArgument : DiagnosticAnalyzer | ||
{ | ||
public const string DIAGNOSTIC_ID = "AG0009"; | ||
|
||
private static readonly LocalizableString Title = new LocalizableResourceString( | ||
nameof(CustomRulesResources.AG0009Title), | ||
CustomRulesResources.ResourceManager, | ||
typeof(CustomRulesResources)); | ||
|
||
private static readonly LocalizableString MessageFormat = new LocalizableResourceString( | ||
nameof(CustomRulesResources.AG0009MessageFormat), | ||
CustomRulesResources.ResourceManager, | ||
typeof(CustomRulesResources)); | ||
|
||
private static readonly LocalizableString Description = | ||
DescriptionContentLoader.GetAnalyzerDescription( | ||
nameof(AG0009IHttpContextAccessorCannotBePassedAsMethodArgument)); | ||
|
||
private static readonly DiagnosticDescriptor Descriptor = | ||
new DiagnosticDescriptor(DIAGNOSTIC_ID, Title, MessageFormat, AnalyzerCategory.CustomQualityRules, | ||
DiagnosticSeverity.Warning, AnalyzerConstants.EnabledByDefault, Description, null, | ||
WellKnownDiagnosticTags.EditAndContinue); | ||
|
||
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => ImmutableArray.Create(Descriptor); | ||
|
||
private static void AnalyzeNode(SyntaxNodeAnalysisContext context) | ||
{ | ||
var methodParam = context.Node as ParameterSyntax; | ||
var paramType = (methodParam.Type as QualifiedNameSyntax)?.Right ?? methodParam.Type as SimpleNameSyntax; | ||
if (paramType == null) | ||
return; | ||
|
||
var paramTypeName = context.SemanticModel.GetTypeInfo(paramType).Type.ToDisplayString(); | ||
if ("Microsoft.AspNetCore.Http.IHttpContextAccessor" == paramTypeName | ||
|| "Microsoft.AspNetCore.Http.HttpContextAccessor" == paramTypeName) | ||
{ | ||
context.ReportDiagnostic(Diagnostic.Create(Descriptor, context.Node.GetLocation())); | ||
} | ||
} | ||
|
||
public override void Initialize(AnalysisContext context) | ||
{ | ||
context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None); | ||
context.EnableConcurrentExecution(); | ||
|
||
context.RegisterSyntaxNodeAction(AnalyzeNode, SyntaxKind.Parameter); | ||
} | ||
} | ||
} |
27 changes: 27 additions & 0 deletions
27
src/Agoda.Analyzers/AgodaCustom/CustomRulesResources.Designer.cs
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
57 changes: 57 additions & 0 deletions
57
...Agoda.Analyzers/RuleContent/AG0009IHttpContextAccessorCannotBePassedAsMethodArgument.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
<p> | ||
Passing the whole <code>Microsoft.AspNetCore.Http.IHttpContextAccessor</code> to your method as a parameter create hard dependency on the IHttpContextAccessor and makes testing really hard ( mocking IHttpContextAccessor itself). | ||
You should only pass parts of the <code>Microsoft.AspNetCore.Http.IHttpContextAccessor</code> that you actually using. | ||
</p> | ||
|
||
<h2>Noncompliant Code Example</h2> | ||
<pre> | ||
using Microsoft.AspNetCore.Http; | ||
|
||
interface ISomething | ||
{ | ||
void SomeMethod(IHttpContextAccessor c, string sampleString); // ugly interface method | ||
void SomeMethod(HttpContextAccessor c, string sampleString); // ugly interface method | ||
} | ||
|
||
class TestClass : ISomething | ||
{ | ||
public void SomeMethod(IHttpContextAccessor context, string sampleString) | ||
{ | ||
// this method is ugly | ||
} | ||
|
||
public void SomeMethod(HttpContextAccessor context, string sampleString) | ||
{ | ||
// this method is ugly | ||
} | ||
|
||
public TestClass(Microsoft.AspNetCore.Http.IHttpContextAccessor context) | ||
{ | ||
// this constructor is uglier | ||
} | ||
|
||
public TestClass(Microsoft.AspNetCore.Http.HttpContextAccessor context) | ||
{ | ||
// this constructor is uglier | ||
} | ||
} | ||
</pre> | ||
|
||
<h2>Compliant Code Example</h2> | ||
<pre> | ||
interface ISomething | ||
{ | ||
void SomeMethod(string userAgent, string sampleString); | ||
} | ||
|
||
class TestClass : ISomething | ||
{ | ||
public void SomeMethod(string userAgent, string sampleString) | ||
{ | ||
} | ||
|
||
public TestClass(string userAgent) | ||
{ | ||
} | ||
} | ||
</pre> |