Skip to content

Commit

Permalink
Merge pull request #17856 from mavasani/IOperationUnitTestGenerator
Browse files Browse the repository at this point in the history
Add helper methods to Verify operation tree for annonated text within…
  • Loading branch information
mavasani authored Mar 15, 2017
2 parents 76fe2a6 + 715e6d7 commit c950069
Show file tree
Hide file tree
Showing 10 changed files with 99 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

namespace Microsoft.CodeAnalysis.CSharp.UnitTests
{
public partial class IOperationTests : CompilingTestBase
public partial class IOperationTests : SemanticModelTestBase
{
[Fact]
[WorkItem(382240, "https://devdiv.visualstudio.com/DevDiv/_workitems?id=382240")]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

namespace Microsoft.CodeAnalysis.CSharp.UnitTests
{
public partial class IOperationTests : CompilingTestBase
public partial class IOperationTests : SemanticModelTestBase
{
[Fact, WorkItem(17595, "https://github.com/dotnet/roslyn/issues/17595")]
public void NoInitializers()
Expand Down
39 changes: 37 additions & 2 deletions src/Compilers/Test/Utilities/CSharp/SemanticModelTestBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,8 @@
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
using Microsoft.CodeAnalysis.Text;
using Microsoft.CodeAnalysis.Test.Utilities;
using Xunit;
using Roslyn.Test.Utilities;

namespace Microsoft.CodeAnalysis.CSharp.UnitTests
{
Expand Down Expand Up @@ -220,5 +219,41 @@ protected CompilationUtils.SemanticInfoSummary GetSemanticInfoForTest(string tes
{
return GetSemanticInfoForTest<ExpressionSyntax>(testSrc);
}

protected string GetOperationTreeForTest<TSyntaxNode>(CSharpCompilation compilation)
where TSyntaxNode: SyntaxNode
{
var tree = compilation.SyntaxTrees[0];
var model = compilation.GetSemanticModel(tree);
SyntaxNode syntaxNode = GetSyntaxNodeOfTypeForBinding<TSyntaxNode>(GetSyntaxNodeList(tree));
if (syntaxNode == null)
{
return null;
}

var operation = model.GetOperationInternal(syntaxNode);
return operation != null ? OperationTreeVerifier.GetOperationTree(operation) : null;
}

protected string GetOperationTreeForTest<TSyntaxNode>(string testSrc, string expectedOperationTree, CSharpParseOptions parseOptions = null)
where TSyntaxNode : SyntaxNode
{
var compilation = CreateCompilationWithMscorlib(testSrc, new[] { SystemCoreRef }, parseOptions: parseOptions);
return GetOperationTreeForTest<TSyntaxNode>(compilation);
}

protected void VerifyOperationTreeForTest<TSyntaxNode>(CSharpCompilation compilation, string expectedOperationTree)
where TSyntaxNode : SyntaxNode
{
var actualOperationTree = GetOperationTreeForTest<TSyntaxNode>(compilation);
OperationTreeVerifier.Verify(expectedOperationTree, actualOperationTree);
}

protected void VerifyOperationTreeForTest<TSyntaxNode>(string testSrc, string expectedOperationTree, CSharpParseOptions parseOptions = null)
where TSyntaxNode : SyntaxNode
{
var actualOperationTree = GetOperationTreeForTest<TSyntaxNode>(testSrc, expectedOperationTree, parseOptions);
OperationTreeVerifier.Verify(expectedOperationTree, actualOperationTree);
}
}
}
29 changes: 29 additions & 0 deletions src/Compilers/Test/Utilities/VisualBasic/SemanticModelTestBase.vb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
' Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

Imports Microsoft.CodeAnalysis.Test.Utilities
Imports Microsoft.CodeAnalysis.Text
Imports Microsoft.CodeAnalysis.VisualBasic.Symbols
Imports Microsoft.CodeAnalysis.VisualBasic.Syntax
Expand Down Expand Up @@ -151,4 +152,32 @@ Public MustInherit Class SemanticModelTestBase : Inherits BasicTestBase
).Where(Function(s) anyArity OrElse DirectCast(s, Symbol).GetArity() = arity.Value).ToList()
End Function

Friend Function GetOperationTreeForTest(Of TSyntaxNode As SyntaxNode)(compilation As VisualBasicCompilation, fileName As String, Optional which As Integer = 0) As String
Dim node As SyntaxNode = CompilationUtils.FindBindingText(Of TSyntaxNode)(compilation, fileName, which)
If node Is Nothing Then
Return Nothing
End If

Dim tree = (From t In compilation.SyntaxTrees Where t.FilePath = fileName).Single()
Dim semanticModel = compilation.GetSemanticModel(tree)
Dim operation = semanticModel.GetOperationInternal(node)
Return If(operation IsNot Nothing, OperationTreeVerifier.GetOperationTree(operation), Nothing)
End Function

Friend Function GetOperationTreeForTest(Of TSyntaxNode As SyntaxNode)(testSrc As String, Optional parseOptions As VisualBasicParseOptions = Nothing, Optional which As Integer = 0) As String
Dim fileName = "a.vb"
Dim syntaxTree = Parse(testSrc, fileName, parseOptions)
Dim compilation = CreateCompilationWithMscorlib(syntaxTree)
Return GetOperationTreeForTest(Of TSyntaxNode)(compilation, fileName, which)
End Function

Friend Sub VerifyOperationTreeForTest(Of TSyntaxNode As SyntaxNode)(compilation As VisualBasicCompilation, fileName As String, expectedOperationTree As String, Optional which As Integer = 0)
Dim actualOperationTree = GetOperationTreeForTest(Of TSyntaxNode)(compilation, fileName, which)
OperationTreeVerifier.Verify(expectedOperationTree, actualOperationTree)
End Sub

Friend Sub VerifyOperationTreeForTest(Of TSyntaxNode As SyntaxNode)(testSrc As String, expectedOperationTree As String, Optional parseOptions As VisualBasicParseOptions = Nothing, Optional which As Integer = 0)
Dim actualOperationTree = GetOperationTreeForTest(Of TSyntaxNode)(testSrc, parseOptions, which)
OperationTreeVerifier.Verify(expectedOperationTree, actualOperationTree)
End Sub
End Class
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Imports Roslyn.Test.Utilities
Namespace Microsoft.CodeAnalysis.VisualBasic.UnitTests.Semantics

Partial Public Class IOperationTests
Inherits BasicTestBase
Inherits SemanticModelTestBase

<Fact>
Public Sub InvalidUserDefinedOperators()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Imports Roslyn.Test.Utilities
Namespace Microsoft.CodeAnalysis.VisualBasic.UnitTests.Semantics

Partial Public Class IOperationTests
Inherits BasicTestBase
Inherits SemanticModelTestBase

<Fact, WorkItem(17595, "https://github.com/dotnet/roslyn/issues/17595")>
Public Sub NoInitializers()
Expand Down
13 changes: 2 additions & 11 deletions src/Test/Utilities/Portable/Compilation/CompilationExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ internal static void VerifyOperationTree(this Compilation compilation, SyntaxNod
var actualTextBuilder = new StringBuilder();
SemanticModel model = compilation.GetSemanticModel(node.SyntaxTree);
AppendOperationTree(model, node, actualTextBuilder);
VerifyOperationTree(expectedOperationTree, actualTextBuilder.ToString());
OperationTreeVerifier.Verify(expectedOperationTree, actualTextBuilder.ToString());
}

internal static void VerifyOperationTree(this Compilation compilation, string expectedOperationTree, bool skipImplicitlyDeclaredSymbols = false)
Expand Down Expand Up @@ -218,7 +218,7 @@ internal static void VerifyOperationTree(this Compilation compilation, string sy
actualTextBuilder.Append(Environment.NewLine);
}

VerifyOperationTree(expectedOperationTree, actualTextBuilder.ToString());
OperationTreeVerifier.Verify(expectedOperationTree, actualTextBuilder.ToString());
}

private static void AppendOperationTree(SemanticModel model, SyntaxNode node, StringBuilder actualTextBuilder, int initialIndent = 0)
Expand All @@ -235,15 +235,6 @@ private static void AppendOperationTree(SemanticModel model, SyntaxNode node, St
}
}

private static void VerifyOperationTree(string expectedOperationTree, string actualOperationTree)
{
char[] newLineChars = Environment.NewLine.ToCharArray();
string actual = actualOperationTree.Trim(newLineChars);
expectedOperationTree = expectedOperationTree.Trim(newLineChars);
expectedOperationTree = Regex.Replace(expectedOperationTree, "([^\r])\n", "$1" + Environment.NewLine);
AssertEx.AreEqual(expectedOperationTree, actual);
}

internal static bool CanHaveExecutableCodeBlock(ISymbol symbol)
{
switch (symbol.Kind)
Expand Down
14 changes: 13 additions & 1 deletion src/Test/Utilities/Portable/Compilation/OperationTreeVerifier.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@
using System.Collections.Immutable;
using System.Diagnostics;
using System.Text;
using System.Text.RegularExpressions;
using Microsoft.CodeAnalysis.Semantics;
using Microsoft.CodeAnalysis.Test.Extensions;
using Roslyn.Test.Utilities;
using Xunit;

namespace Microsoft.CodeAnalysis.Test.Utilities
Expand Down Expand Up @@ -42,6 +44,15 @@ public static string GetOperationTree(IOperation operation, int initialIndent =
return walker._builder.ToString();
}

public static void Verify(string expectedOperationTree, string actualOperationTree)
{
char[] newLineChars = Environment.NewLine.ToCharArray();
string actual = actualOperationTree.Trim(newLineChars);
expectedOperationTree = expectedOperationTree.Trim(newLineChars);
expectedOperationTree = Regex.Replace(expectedOperationTree, "([^\r])\n", "$1" + Environment.NewLine);
AssertEx.AreEqual(expectedOperationTree, actual);
}

#region Logging helpers

private void LogCommonPropertiesAndNewLine(IOperation operation)
Expand Down Expand Up @@ -208,7 +219,8 @@ private void VisitInstanceExpression(IOperation instance)

internal override void VisitNoneOperation(IOperation operation)
{
Assert.True(false, "Encountered an IOperation with `Kind == OperationKind.None` while walking the operation tree.");
LogString("IOperation: ");
LogCommonPropertiesAndNewLine(operation);
}

public override void VisitBlockStatement(IBlockStatement operation)
Expand Down
13 changes: 13 additions & 0 deletions src/Test/Utilities/Portable/Extensions/SemanticModelExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

namespace Microsoft.CodeAnalysis.Test.Extensions
{
public static class SemanticModelExtensions
{
public static IOperation GetOperationInternal(this SemanticModel model, SyntaxNode node)
{
// Invoke the GetOperationInternal API to by-pass the IOperation feature flag check.
return model.GetOperationInternal(node);
}
}
}
1 change: 1 addition & 0 deletions src/Test/Utilities/Portable/TestUtilities.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@
<Compile Include="Diagnostics\TrackingDiagnosticAnalyzer.cs" />
<Compile Include="ExceptionHelper.cs" />
<Compile Include="CompilerTraitAttribute.cs" />
<Compile Include="Extensions\SemanticModelExtensions.cs" />
<Compile Include="Extensions\SymbolExtensions.cs" />
<Compile Include="FX\ConsoleOutput.cs" />
<Compile Include="FX\CultureHelpers.cs" />
Expand Down

0 comments on commit c950069

Please sign in to comment.