Skip to content

Commit

Permalink
Address code review comments
Browse files Browse the repository at this point in the history
  • Loading branch information
costin-zaharia-sonarsource committed Feb 18, 2022
1 parent ab804b0 commit d3ebb2e
Show file tree
Hide file tree
Showing 8 changed files with 132 additions and 39 deletions.
33 changes: 33 additions & 0 deletions analyzers/src/SonarAnalyzer.CSharp/Helpers/SafeSyntaxWalker.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* SonarAnalyzer for .NET
* Copyright (C) 2015-2022 SonarSource SA
* mailto: contact AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/

using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using SonarAnalyzer.Common;
using SonarAnalyzer.Extensions;

namespace SonarAnalyzer.Helpers
{
public class SafeSyntaxWalker : CSharpSyntaxWalker, ISafeSyntaxWalker
{
public bool SafeVisit(SyntaxNode syntaxNode) =>
CSharpSyntaxWalkerExtensions.SafeVisit(this, syntaxNode); // ToDo: Replace the extension method with this class.
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,8 @@
*/

using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using SonarAnalyzer.Extensions;
using SonarAnalyzer.Common;
using SonarAnalyzer.Helpers;
using StyleCop.Analyzers.Lightup;

Expand All @@ -33,26 +32,20 @@ public class LocksReleasedAllPaths : LocksReleasedAllPathsBase

protected override DiagnosticDescriptor Rule => S2222;

protected override void Visit(SyntaxNode node, LockAcquireReleaseCollector collector)
{
var walker = new LockAcquireReleaseWalker(collector);
walker.SafeVisit(NodeContext.Node);
}
protected override ISafeSyntaxWalker GetSyntaxWalker(LockAcquireReleaseCollector collector) => new LockAcquireReleaseWalker(collector);

private sealed class LockAcquireReleaseWalker : CSharpSyntaxWalker
private sealed class LockAcquireReleaseWalker : SafeSyntaxWalker
{
private readonly LockAcquireReleaseCollector collector;

public LockAcquireReleaseWalker(LockAcquireReleaseCollector collector)
{
public LockAcquireReleaseWalker(LockAcquireReleaseCollector collector) =>
this.collector = collector;
}

public override void Visit(SyntaxNode node)
{
if (collector.LockAcquiredAndReleased
// Lambda expressions and local functions are analyzed separately.
|| node is LambdaExpressionSyntax or ParenthesizedLambdaExpressionSyntax
// Lambda expressions, anonymous methods and local functions are analyzed separately.
|| node is AnonymousFunctionExpressionSyntax
|| LocalFunctionStatementSyntaxWrapper.IsInstance(node))
{
return;
Expand Down
29 changes: 29 additions & 0 deletions analyzers/src/SonarAnalyzer.Common/Common/ISafeSyntaxWalker.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* SonarAnalyzer for .NET
* Copyright (C) 2015-2022 SonarSource SA
* mailto: contact AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/

using Microsoft.CodeAnalysis;

namespace SonarAnalyzer.Common
{
public interface ISafeSyntaxWalker
{
public bool SafeVisit(SyntaxNode syntaxNode);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
using System.Collections.Generic;
using System.Linq;
using Microsoft.CodeAnalysis;
using SonarAnalyzer.Common;
using SonarAnalyzer.Helpers;
using SonarAnalyzer.SymbolicExecution.Constraints;
using StyleCop.Analyzers.Lightup;
Expand All @@ -46,7 +47,7 @@ public abstract class LocksReleasedAllPathsBase : SymbolicRuleCheck
"TryEnterWriteLock"
};

protected abstract void Visit(SyntaxNode node, LockAcquireReleaseCollector collector);
protected abstract ISafeSyntaxWalker GetSyntaxWalker(LockAcquireReleaseCollector collector);

public override ProgramState PostProcess(SymbolicContext context)
{
Expand Down Expand Up @@ -118,7 +119,11 @@ public override void ExecutionCompleted()
public override bool ShouldExecute()
{
var collector = new LockAcquireReleaseCollector();
Visit(NodeContext.Node, collector);
var walker = GetSyntaxWalker(collector);
foreach (var child in NodeContext.Node.ChildNodes())
{
walker.SafeVisit(child);
}
return collector.LockAcquiredAndReleased;
}

Expand Down Expand Up @@ -196,18 +201,9 @@ protected sealed class LockAcquireReleaseCollector

public void RegisterIdentifier(string name)
{
lockAcquired |= IsLockType(name) || IsLockMethod(name);
lockReleased |= IsReleaseMethod(name);
lockAcquired = lockAcquired || LockTypes.Contains(name) || LockMethods.Contains(name);
lockReleased = lockReleased || ReleaseMethods.Contains(name);
}

private static bool IsLockType(string name) =>
LockTypes.Contains(name);

private static bool IsLockMethod(string name) =>
LockMethods.Contains(name);

private static bool IsReleaseMethod(string name) =>
ReleaseMethods.Contains(name);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* SonarAnalyzer for .NET
* Copyright (C) 2015-2022 SonarSource SA
* mailto: contact AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/

using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.VisualBasic;
using SonarAnalyzer.Common;

namespace SonarAnalyzer.Helpers
{
public class SafeSyntaxWalker : VisualBasicSyntaxWalker, ISafeSyntaxWalker
{
public bool SafeVisit(SyntaxNode syntaxNode) =>
VisualBasicSyntaxWalkerHelper.SafeVisit(this, syntaxNode); // ToDo: Replace the extension method with this class.
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@
*/

using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.VisualBasic;
using Microsoft.CodeAnalysis.VisualBasic.Syntax;
using SonarAnalyzer.Common;
using SonarAnalyzer.Helpers;

namespace SonarAnalyzer.SymbolicExecution.Roslyn.RuleChecks.VisualBasic
Expand All @@ -31,20 +31,14 @@ public class LocksReleasedAllPaths : LocksReleasedAllPathsBase

protected override DiagnosticDescriptor Rule => S2222;

protected override void Visit(SyntaxNode node, LockAcquireReleaseCollector collector)
{
var walker = new LockAcquireReleaseWalker(collector);
walker.SafeVisit(NodeContext.Node);
}
protected override ISafeSyntaxWalker GetSyntaxWalker(LockAcquireReleaseCollector collector) => new LockAcquireReleaseWalker(collector);

private sealed class LockAcquireReleaseWalker : VisualBasicSyntaxWalker
private sealed class LockAcquireReleaseWalker : SafeSyntaxWalker
{
private readonly LockAcquireReleaseCollector collector;

public LockAcquireReleaseWalker(LockAcquireReleaseCollector collector)
{
public LockAcquireReleaseWalker(LockAcquireReleaseCollector collector) =>
this.collector = collector;
}

public override void Visit(SyntaxNode node)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ class Program

public object PublicObject = new object();

delegate void VoidDelegate();

private bool condition;

public void Method1()
Expand Down Expand Up @@ -329,9 +331,16 @@ public int MyProperty

public void Lambda(bool condition)
{
Action action = () =>
Action parenthesizedLambda = () =>
{
Monitor.Enter(obj); // // FN, lambdas are not yet supported
Monitor.Enter(obj); // Noncompliant
if (condition)
Monitor.Exit(obj);
};

Action<int> simpleLambda = x =>
{
Monitor.Enter(obj); // Noncompliant
if (condition)
Monitor.Exit(obj);
};
Expand All @@ -350,6 +359,13 @@ static void StaticLocalFunction()
if (1 == 2)
Monitor.Exit(l);
}

VoidDelegate anonymousMethod = delegate
{
Monitor.Enter(other); // Noncompliant
if (condition)
Monitor.Exit(other);
};
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ Namespace Monitor_Conditions

Public Sub Lambda()
Dim l = Function(value)
Monitor.Enter(Obj) ' FN, lambdas are not supported yet
Monitor.Enter(Obj) ' Noncompliant
If value = 42 Then Monitor.Exit(Obj)
Return value
End Function
Expand Down

0 comments on commit d3ebb2e

Please sign in to comment.