Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion 2 runTestsCS.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ param([String]$testClass)
$testDllDirPath = "$PSScriptRoot\test\CSharp\CodeCracker.Test\bin\Debug\"
$testDllFileName = "CodeCracker.Test.CSharp.dll"
$testDllFullFileName = "$testDllDirPath$testDllFileName"
$xunitConsole = "$PSScriptRoot\packages\xunit.runner.console.2.2.0\tools\xunit.console.x86.exe"
$xunitConsole = "$PSScriptRoot\packages\xunit.runner.console.2.3.1\tools\net452\xunit.console.exe"

if (!(gcm nodemon -ErrorAction Ignore)) {
Write-Host -ForegroundColor DarkRed 'Nodemon not found, install it with npm: `npm i -g nodemon`'
Expand Down
2 changes: 1 addition & 1 deletion 2 runTestsVB.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ param([String]$testClass)
$testDllDirPath = "$PSScriptRoot\test\VisualBasic\CodeCracker.Test\bin\Debug\"
$testDllFileName = "CodeCracker.Test.VisualBasic.dll"
$testDllFullFileName = "$testDllDirPath$testDllFileName"
$xunitConsole = "$PSScriptRoot\packages\xunit.runner.console.2.2.0\tools\xunit.console.x86.exe"
$xunitConsole = "$PSScriptRoot\packages\xunit.runner.console.2.3.1\tools\net452\xunit.console.exe"

if (!(gcm nodemon -ErrorAction Ignore)) {
Write-Host -ForegroundColor DarkRed 'Nodemon not found, install it with npm: `npm i -g nodemon`'
Expand Down
29 changes: 27 additions & 2 deletions 29 src/CSharp/CodeCracker/Style/SwitchToAutoPropAnalyzer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Diagnostics;
using System;
using System.Collections.Immutable;
using System.Linq;

Expand Down Expand Up @@ -57,6 +56,12 @@ private static void AnalyzeProperty(SyntaxNodeAnalysisContext context, bool canH
if (returnIdentifier == null) return;
var semanticModel = context.SemanticModel;
var fieldSymbol = semanticModel.GetSymbolInfo(returnIdentifier).Symbol;
var outerClass = context.Node.Ancestors().OfType<ClassDeclarationSyntax>().LastOrDefault();
if (outerClass != null && IsBackingFieldRefOrOutParam(fieldSymbol, outerClass, semanticModel))
{
return;
}

if (fieldSymbol == null) return;
var assignmentLeftIdentifier = (setterAssignmentExpression.Left is MemberAccessExpressionSyntax &&
((MemberAccessExpressionSyntax)setterAssignmentExpression.Left).Expression is ThisExpressionSyntax ? ((MemberAccessExpressionSyntax)setterAssignmentExpression.Left).Name : setterAssignmentExpression.Left) as IdentifierNameSyntax;
Expand All @@ -79,5 +84,25 @@ private static void AnalyzeProperty(SyntaxNodeAnalysisContext context, bool canH
var diag = Diagnostic.Create(Rule, property.GetLocation(), property.Identifier.Text);
context.ReportDiagnostic(diag);
}

private static bool IsBackingFieldRefOrOutParam(ISymbol fieldSymbol, ClassDeclarationSyntax outerClass, SemanticModel semanticModel)
{
foreach (var descendant in outerClass.DescendantNodes().OfType<IdentifierNameSyntax>())
{
var descendentSymbol = semanticModel.GetSymbolInfo(descendant).Symbol;
if (descendentSymbol != null && descendentSymbol.Equals(fieldSymbol))
{
// The field is being referenced
// Next we check whether it is referenced as an argument and passed by ref/out
var argument = descendant.AncestorsAndSelf().OfType<ArgumentSyntax>().FirstOrDefault();
if (argument != null && !argument.RefOrOutKeyword.IsKind(SyntaxKind.None))
{
return true;
}
}
}

return false;
}
}
}
}
63 changes: 63 additions & 0 deletions 63 test/CSharp/CodeCracker.Test/Style/SwitchToAutoPropTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,69 @@ public int Id
await VerifyCSharpHasNoDiagnosticsAsync(source, LanguageVersion.CSharp5);
}

[Fact]
public async Task IgnoresWhenPropertyIsUsedWithOut()
{
const string source = @"
namespace ConsoleApplication1
{
class CC0017
{
public int MyThing
{
get { return _myThing; }
set { _myThing = value; }
}
private int _myThing;

public static void SetOut(ref int field)
{
field = 42;
}

public CC0017()
{
SetOut(ref _myThing);
}
}
}";
await VerifyCSharpHasNoDiagnosticsAsync(source);
}

[Fact]
public async Task IgnoresWhenPropertyIsUsedWithRef()
{
const string source = @"
namespace ConsoleApplication1
{
class CC0017
{
public int MyThing
{
get { return _myThing; }
set { _myThing = value; }
}
private int _myThing;

public void IncrementRef()
{
Interlocked.Increment(ref _myThing);
}

public static void SetOut(out int field)
{
field = 42;
}

public CC0017()
{
SetOut(out _myThing);
}
}
}";
await VerifyCSharpHasNoDiagnosticsAsync(source);
}

[Fact]
public async Task SimplePropertyCreatesDiagnostic()
{
Expand Down
Morty Proxy This is a proxified and sanitized view of the page, visit original site.