diff --git a/build/Targets/GenerateCompilerExecutableBindingRedirects.targets b/build/Targets/GenerateCompilerExecutableBindingRedirects.targets index 049ab8e118f9d..9141f1ddc3996 100644 --- a/build/Targets/GenerateCompilerExecutableBindingRedirects.targets +++ b/build/Targets/GenerateCompilerExecutableBindingRedirects.targets @@ -25,7 +25,7 @@ $(AssemblyVersion) - 1.2.1.0 + 1.2.3.0 4.0.1.0 @@ -49,7 +49,7 @@ 4.0.1.0 - 1.4.1.0 + 1.4.3.0 4.0.1.0 diff --git a/build/Targets/Packages.props b/build/Targets/Packages.props index 3d69dbfcd5dec..b61dfe6f12172 100644 --- a/build/Targets/Packages.props +++ b/build/Targets/Packages.props @@ -40,18 +40,18 @@ 4.3.0 0.8.31-beta 1.0.35 - 1.2.0 - 1.1.0-beta1-62628-01 - 1.1.0-beta1-62628-01 + 1.3.0-beta-62801-02 + 1.1.0-beta1-62801-01 + 1.1.0-beta1-62801-01 1.7.0 - 1.4.0 + 1.5.0-beta-62801-02 4.7.2-alpha-00001 1.0.27-prerelease-01811-02 2.1.0-prerelease-02419-02 3.13.8 15.0.26730-alpha 14.3.25407-alpha - 1.0.0-beta1-61531-03 + 1.0.0-beta1-62801-01 8.0.0.0-alpha 15.6.0-dev @@ -158,7 +158,7 @@ 4.3.0 4.3.0 4.3.0 - 1.3.1 + 1.5.0-preview2-26401-03 4.3.0 4.3.0 4.3.0 @@ -191,7 +191,7 @@ 4.3.0 4.3.0 4.3.0 - 1.4.2 + 1.6.0-preview2-26401-03 4.3.0 4.3.0 4.3.0 diff --git a/build/Targets/Roslyn.Toolsets.Xunit.targets b/build/Targets/Roslyn.Toolsets.Xunit.targets index 16fdab15295ee..d8c45d9ea7e43 100644 --- a/build/Targets/Roslyn.Toolsets.Xunit.targets +++ b/build/Targets/Roslyn.Toolsets.Xunit.targets @@ -20,7 +20,7 @@ true true - $(RoslynDesktopRuntimeIdentifier) + $(RoslynDesktopRuntimeIdentifier) diff --git a/build/Targets/Settings.props b/build/Targets/Settings.props index c4f11d084b8af..877b9d3d19c60 100644 --- a/build/Targets/Settings.props +++ b/build/Targets/Settings.props @@ -37,8 +37,7 @@ False $(NuGetPackageRoot)/microsoft.net.roslyndiagnostics/$(RoslynDiagnosticsNugetPackageVersion)/build/Microsoft.Net.RoslynDiagnostics.props - net461;netcoreapp2.0 - net46;netcoreapp2.0 + net46;netcoreapp2.0 win;win-x64;linux-x64;osx-x64 win win-x86 diff --git a/build/ToolsetPackages/RoslynToolset.csproj b/build/ToolsetPackages/RoslynToolset.csproj index 14c542989b43c..cadfc16ce6ba9 100644 --- a/build/ToolsetPackages/RoslynToolset.csproj +++ b/build/ToolsetPackages/RoslynToolset.csproj @@ -19,7 +19,7 @@ - + diff --git a/build/config/SignToolData.json b/build/config/SignToolData.json index e4ea966a1a817..f21526e2fdd12 100644 --- a/build/config/SignToolData.json +++ b/build/config/SignToolData.json @@ -106,7 +106,7 @@ "strongName": null, "values": [ "Dlls\\ServicesTestUtilities\\Roslyn.Services.Test.Utilities.dll", - "Dlls\\TestUtilities\\net461\\Roslyn.Test.Utilities.dll", + "Dlls\\TestUtilities\\net46\\Roslyn.Test.Utilities.dll", "Dlls\\VisualStudioIntegrationTestUtilities\\Microsoft.VisualStudio.IntegrationTest.Utilities.dll", "Vsix\\VisualStudioIntegrationTestSetup\\Microsoft.VisualStudio.IntegrationTest.Setup.dll" ] @@ -144,7 +144,9 @@ "Vsix\\VisualStudioSetup.Next\\Roslyn.VisualStudio.Setup.Next.vsix", "Vsix\\VisualStudioSetup\\Roslyn.VisualStudio.Setup.vsix", "Vsix\\Roslyn\\RoslynDeployment.vsix", - "Vsix\\VisualStudioIntegrationTestSetup\\Microsoft.VisualStudio.IntegrationTest.Setup.vsix" + "Vsix\\VisualStudioIntegrationTestSetup\\Microsoft.VisualStudio.IntegrationTest.Setup.vsix", + "Vsix\\CodeAnalysisCompilers\\Microsoft.CodeAnalysis.Compilers.vsix", + "Vsix\\PortableFacades\\PortableFacades.vsix" ] }, { @@ -224,14 +226,19 @@ "System.IO.Pipes.AccessControl.dll", "System.IO.Pipes.dll", "System.IO.dll", + "System.Net.Security.dll", + "System.Net.Sockets.dll", "System.Reflection.Metadata.1.0.21.nupkg", "System.Reflection.Metadata.dll", + "System.Reflection.TypeExtensions.dll", "System.Reflection.dll", "System.Resources.Reader.dll", "System.Runtime.InteropServices.RuntimeInformation.dll", + "System.Runtime.Serialization.Primitives.dll", "System.Security.AccessControl.dll", "System.Security.Claims.dll", "System.Security.Cryptography.Algorithms.dll", + "System.Security.Cryptography.Csp.dll", "System.Security.Cryptography.Encoding.dll", "System.Security.Cryptography.Primitives.dll", "System.Security.Cryptography.X509Certificates.dll", diff --git a/build/scripts/build-utils.ps1 b/build/scripts/build-utils.ps1 index e7e82c7d46cca..e546b0fa90ffc 100644 --- a/build/scripts/build-utils.ps1 +++ b/build/scripts/build-utils.ps1 @@ -136,7 +136,6 @@ function Ensure-NuGet() { # Ensure the proper SDK in installed in our %PATH%. This is how MSBuild locates the # SDK. Returns the location to the dotnet exe function Ensure-DotnetSdk() { - # Check to see if the specified dotnet installations meets our build requirements function Test-DotnetDir([string]$dotnetDir, [string]$runtimeVersion, [string]$sdkVersion) { $sdkPath = Join-Path $dotnetDir "sdk\$sdkVersion" @@ -180,6 +179,9 @@ function Ensure-DotnetSdk() { Exec-Block { & $destFile -Version $sdkVersion -InstallDir $cliDir } | Out-Null Exec-Block { & $destFile -Version $runtimeVersion -SharedRuntime -InstallDir $cliDir } | Out-Null } + else { + ${env:PATH} = "$cliDir;${env:PATH}" + } return (Join-Path $cliDir "dotnet.exe") } diff --git a/build/scripts/build.ps1 b/build/scripts/build.ps1 index da5945bfe47f9..d3d7090fcdb87 100644 --- a/build/scripts/build.ps1 +++ b/build/scripts/build.ps1 @@ -180,7 +180,10 @@ function Restore-Packages() { Write-Host "Restoring $($both[0])" $projectFilePath = $both[1] $projectFileName = [IO.Path]::GetFileNameWithoutExtension($projectFilePath) - $logFilePath = Join-Path $logsDir "Restore-$($projectFileName).binlog" + $logFilePath = "" + if ($binaryLog) { + $logFilePath = Join-Path $logsDir "Restore-$($projectFileName).binlog" + } Restore-Project $dotnet $both[1] $logFilePath } } @@ -283,6 +286,10 @@ function Build-ExtraSignArtifacts() { Run-MSBuild "..\Compilers\Server\VBCSCompiler\VBCSCompiler.csproj" "/p:TargetFramework=netcoreapp2.0 /t:PublishWithoutBuilding" Write-Host "Publishing MSBuildTask" Run-MSBuild "..\Compilers\Core\MSBuildTask\MSBuildTask.csproj" "/p:TargetFramework=netcoreapp2.0 /t:PublishWithoutBuilding" + Write-Host "Building PortableFacades Swix" + Run-MSBuild "DevDivVsix\PortableFacades\PortableFacades.swixproj" + Write-Host "Building CompilersCodeAnalysis Swix" + Run-MSBuild "DevDivVsix\CompilersPackage\Microsoft.CodeAnalysis.Compilers.swixproj" $dest = @($configDir) foreach ($dir in $dest) { diff --git a/build/scripts/tests.sh b/build/scripts/tests.sh index 14e5066bac5e5..106d4f1bb8a55 100755 --- a/build/scripts/tests.sh +++ b/build/scripts/tests.sh @@ -22,7 +22,7 @@ if [[ "${runtime}" == "dotnet" ]]; then target_framework=netcoreapp2.0 xunit_console="${nuget_dir}"/xunit.runner.console/"${xunit_console_version}"/tools/${target_framework}/xunit.console.dll elif [[ "${runtime}" == "mono" ]]; then - target_framework=net461 + target_framework=net46 xunit_console="${nuget_dir}"/xunit.runner.console/"${xunit_console_version}"/tools/net452/xunit.console.exe else echo "Unknown runtime: ${runtime}" diff --git a/src/Compilers/CSharp/Portable/Binder/Binder.ValueChecks.cs b/src/Compilers/CSharp/Portable/Binder/Binder.ValueChecks.cs index 502792ec560a2..d1b0547da16bb 100644 --- a/src/Compilers/CSharp/Portable/Binder/Binder.ValueChecks.cs +++ b/src/Compilers/CSharp/Portable/Binder/Binder.ValueChecks.cs @@ -2328,8 +2328,20 @@ internal static uint GetValEscape(BoundExpression expr, uint scopeOfTheContainin // Unsafe code will always be allowed to escape. return Binder.ExternalScope; + case BoundKind.AsOperator: + case BoundKind.AwaitExpression: + case BoundKind.ConditionalAccess: + case BoundKind.NullCoalescingOperator: + case BoundKind.ArrayAccess: + // only possible in error cases (if possible at all) + return scopeOfTheContainingExpression; + default: - throw ExceptionUtilities.UnexpectedValue($"{expr.Kind} expression of {expr.Type} type"); + // in error situations some unexpected nodes could make here + // returning "scopeOfTheContainingExpression" seems safer than throwing. + // we will still assert to make sure that all nodes are accounted for. + Debug.Assert(false, $"{expr.Kind} expression of {expr.Type} type"); + return scopeOfTheContainingExpression; } } @@ -2643,8 +2655,20 @@ internal static bool CheckValEscape(SyntaxNode node, BoundExpression expr, uint var operandExpression = ((BoundPointerIndirectionOperator)expr).Operand; return CheckValEscape(operandExpression.Syntax, operandExpression, escapeFrom, escapeTo, checkingReceiver, diagnostics); + case BoundKind.AsOperator: + case BoundKind.AwaitExpression: + case BoundKind.ConditionalAccess: + case BoundKind.NullCoalescingOperator: + case BoundKind.ArrayAccess: + // only possible in error cases (if possible at all) + return false; + default: - throw ExceptionUtilities.UnexpectedValue($"{expr.Kind} expression of {expr.Type} type"); + // in error situations some unexpected nodes could make here + // returning "false" seems safer than throwing. + // we will still assert to make sure that all nodes are accounted for. + Debug.Assert(false, $"{expr.Kind} expression of {expr.Type} type"); + return false; #region "cannot produce ref-like values" // case BoundKind.ThrowExpression: @@ -2652,11 +2676,7 @@ internal static bool CheckValEscape(SyntaxNode node, BoundExpression expr, uint // case BoundKind.ArgList: // case BoundKind.RefTypeOperator: // case BoundKind.AddressOfOperator: -// case BoundKind.AsOperator: // case BoundKind.TypeOfOperator: -// case BoundKind.ArrayAccess: -// case BoundKind.NullCoalescingOperator: -// case BoundKind.AwaitExpression: // case BoundKind.IsOperator: // case BoundKind.SizeOfOperator: // case BoundKind.DynamicMemberAccess: @@ -2674,7 +2694,6 @@ internal static bool CheckValEscape(SyntaxNode node, BoundExpression expr, uint // case BoundKind.NoPiaObjectCreationExpression: // case BoundKind.BaseReference: // case BoundKind.Literal: -// case BoundKind.ConditionalAccess: // case BoundKind.IsPatternExpression: // case BoundKind.DeconstructionAssignmentOperator: // case BoundKind.EventAccess: diff --git a/src/Compilers/CSharp/Portable/Binder/Binder_Statements.cs b/src/Compilers/CSharp/Portable/Binder/Binder_Statements.cs index a83438d4e6d24..ce6fe2db6ef18 100644 --- a/src/Compilers/CSharp/Portable/Binder/Binder_Statements.cs +++ b/src/Compilers/CSharp/Portable/Binder/Binder_Statements.cs @@ -492,50 +492,61 @@ private BoundStatement BindLocalFunctionStatement(LocalFunctionStatementSyntax n var hasErrors = localSymbol.ScopeBinder .ValidateDeclarationNameConflictsInScope(localSymbol, diagnostics); - BoundBlock block; + BoundBlock blockBody = null; + BoundBlock expressionBody = null; if (node.Body != null) { - block = BindEmbeddedBlock(node.Body, diagnostics); + blockBody = runAnalysis(BindEmbeddedBlock(node.Body, diagnostics), diagnostics); + + if (node.ExpressionBody != null) + { + var expressionBodyDiagnostics = new DiagnosticBag(); + expressionBody = runAnalysis(BindExpressionBodyAsBlock(node.ExpressionBody, expressionBodyDiagnostics), expressionBodyDiagnostics); + } } else if (node.ExpressionBody != null) { - block = BindExpressionBodyAsBlock(node.ExpressionBody, diagnostics); + expressionBody = runAnalysis(BindExpressionBodyAsBlock(node.ExpressionBody, diagnostics), diagnostics); } else { - block = null; hasErrors = true; diagnostics.Add(ErrorCode.ERR_LocalFunctionMissingBody, localSymbol.Locations[0], localSymbol); } - if (block != null) - { - localSymbol.ComputeReturnType(); - - // Have to do ControlFlowPass here because in MethodCompiler, we don't call this for synthed methods - // rather we go directly to LowerBodyOrInitializer, which skips over flow analysis (which is in CompileMethod) - // (the same thing - calling ControlFlowPass.Analyze in the lowering - is done for lambdas) - // It's a bit of code duplication, but refactoring would make things worse. - var endIsReachable = ControlFlowPass.Analyze(localSymbol.DeclaringCompilation, localSymbol, block, diagnostics); - if (endIsReachable) - { - if (ImplicitReturnIsOkay(localSymbol)) - { - block = FlowAnalysisPass.AppendImplicitReturn(block, localSymbol); - } - else - { - diagnostics.Add(ErrorCode.ERR_ReturnExpected, localSymbol.Locations[0], localSymbol); - } - } - } + Debug.Assert(blockBody != null || expressionBody != null || hasErrors); localSymbol.GetDeclarationDiagnostics(diagnostics); Symbol.CheckForBlockAndExpressionBody( node.Body, node.ExpressionBody, node, diagnostics); - return new BoundLocalFunctionStatement(node, localSymbol, block, hasErrors); + return new BoundLocalFunctionStatement(node, localSymbol, blockBody, expressionBody, hasErrors); + + BoundBlock runAnalysis(BoundBlock block, DiagnosticBag blockDiagnostics) + { + if (block != null) + { + // Have to do ControlFlowPass here because in MethodCompiler, we don't call this for synthed methods + // rather we go directly to LowerBodyOrInitializer, which skips over flow analysis (which is in CompileMethod) + // (the same thing - calling ControlFlowPass.Analyze in the lowering - is done for lambdas) + // It's a bit of code duplication, but refactoring would make things worse. + var endIsReachable = ControlFlowPass.Analyze(localSymbol.DeclaringCompilation, localSymbol, block, blockDiagnostics); + if (endIsReachable) + { + if (ImplicitReturnIsOkay(localSymbol)) + { + block = FlowAnalysisPass.AppendImplicitReturn(block, localSymbol); + } + else + { + blockDiagnostics.Add(ErrorCode.ERR_ReturnExpected, localSymbol.Locations[0], localSymbol); + } + } + } + + return block; + } } private bool ImplicitReturnIsOkay(MethodSymbol method) diff --git a/src/Compilers/CSharp/Portable/BoundTree/BoundLocalFunctionStatement.cs b/src/Compilers/CSharp/Portable/BoundTree/BoundLocalFunctionStatement.cs new file mode 100644 index 0000000000000..0f217846e735b --- /dev/null +++ b/src/Compilers/CSharp/Portable/BoundTree/BoundLocalFunctionStatement.cs @@ -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. + +using System; +using System.Collections.Generic; +using System.Text; + +namespace Microsoft.CodeAnalysis.CSharp +{ + internal partial class BoundLocalFunctionStatement + { + public BoundBlock Body { get => BlockBody ?? ExpressionBody; } + } +} diff --git a/src/Compilers/CSharp/Portable/BoundTree/BoundNodes.xml b/src/Compilers/CSharp/Portable/BoundTree/BoundNodes.xml index 12aa250318354..310bb982d3085 100644 --- a/src/Compilers/CSharp/Portable/BoundTree/BoundNodes.xml +++ b/src/Compilers/CSharp/Portable/BoundTree/BoundNodes.xml @@ -742,7 +742,8 @@ --> - + + diff --git a/src/ExpressionEvaluator/VisualBasic/Test/ExpressionCompiler/BasicExpressionCompilerTest.vbproj b/src/ExpressionEvaluator/VisualBasic/Test/ExpressionCompiler/BasicExpressionCompilerTest.vbproj index 5fecdd14d284d..79064a00e6527 100644 --- a/src/ExpressionEvaluator/VisualBasic/Test/ExpressionCompiler/BasicExpressionCompilerTest.vbproj +++ b/src/ExpressionEvaluator/VisualBasic/Test/ExpressionCompiler/BasicExpressionCompilerTest.vbproj @@ -7,7 +7,7 @@ AnyCPU Library Roslyn.ExpressionEvaluator.VisualBasic.ExpressionCompiler.UnitTests - net461 + net46 $(RoslynDesktopRuntimeIdentifier) UnitTest diff --git a/src/ExpressionEvaluator/VisualBasic/Test/ResultProvider/BasicResultProviderTest.vbproj b/src/ExpressionEvaluator/VisualBasic/Test/ResultProvider/BasicResultProviderTest.vbproj index 31380a44ca61b..96bb17f7b2b16 100644 --- a/src/ExpressionEvaluator/VisualBasic/Test/ResultProvider/BasicResultProviderTest.vbproj +++ b/src/ExpressionEvaluator/VisualBasic/Test/ResultProvider/BasicResultProviderTest.vbproj @@ -7,7 +7,7 @@ AnyCPU Library Roslyn.ExpressionEvaluator.VisualBasic.ResultProvider.UnitTests - net461 + net46 $(RoslynDesktopRuntimeIdentifier) Default UnitTest diff --git a/src/Features/CSharp/Portable/CSharpFeaturesResources.Designer.cs b/src/Features/CSharp/Portable/CSharpFeaturesResources.Designer.cs index c94812ab67804..881a84f93d3b2 100644 --- a/src/Features/CSharp/Portable/CSharpFeaturesResources.Designer.cs +++ b/src/Features/CSharp/Portable/CSharpFeaturesResources.Designer.cs @@ -288,20 +288,29 @@ internal static string conversion_operator { } /// - /// Looks up a localized string similar to Convert 'for' to 'foreach'. + /// Looks up a localized string similar to Convert to 'for'. /// - internal static string Convert_for_to_foreach { + internal static string Convert_to_for { get { - return ResourceManager.GetString("Convert_for_to_foreach", resourceCulture); + return ResourceManager.GetString("Convert_to_for", resourceCulture); } } /// - /// Looks up a localized string similar to Convert 'if' to 'switch'. + /// Looks up a localized string similar to Convert to 'foreach'. /// - internal static string Convert_if_to_switch { + internal static string Convert_to_foreach { get { - return ResourceManager.GetString("Convert_if_to_switch", resourceCulture); + return ResourceManager.GetString("Convert_to_foreach", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Convert to 'switch'. + /// + internal static string Convert_to_switch { + get { + return ResourceManager.GetString("Convert_to_switch", resourceCulture); } } diff --git a/src/Features/CSharp/Portable/CSharpFeaturesResources.resx b/src/Features/CSharp/Portable/CSharpFeaturesResources.resx index 33729d573f118..dc26cb8b8afb6 100644 --- a/src/Features/CSharp/Portable/CSharpFeaturesResources.resx +++ b/src/Features/CSharp/Portable/CSharpFeaturesResources.resx @@ -497,8 +497,8 @@ Add 'this.' - - Convert 'if' to 'switch' + + Convert to 'switch' Warning: Extracting a local function reference may produce invalid code @@ -521,7 +521,10 @@ Add parentheses - - Convert 'for' to 'foreach' + + Convert to 'foreach' + + + Convert to 'for' \ No newline at end of file diff --git a/src/Features/CSharp/Portable/ConvertForEachToFor/CSharpConvertForEachToForCodeRefactoringProvider.cs b/src/Features/CSharp/Portable/ConvertForEachToFor/CSharpConvertForEachToForCodeRefactoringProvider.cs new file mode 100644 index 0000000000000..5399da0dfb16a --- /dev/null +++ b/src/Features/CSharp/Portable/ConvertForEachToFor/CSharpConvertForEachToForCodeRefactoringProvider.cs @@ -0,0 +1,161 @@ +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Composition; +using System.Threading; +using Microsoft.CodeAnalysis.CodeActions; +using Microsoft.CodeAnalysis.CodeRefactorings; +using Microsoft.CodeAnalysis.ConvertForEachToFor; +using Microsoft.CodeAnalysis.CSharp.CodeStyle.TypeStyle; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using Microsoft.CodeAnalysis.Editing; +using Microsoft.CodeAnalysis.Formatting; +using Microsoft.CodeAnalysis.Options; +using Microsoft.CodeAnalysis.Text; +using Roslyn.Utilities; + +namespace Microsoft.CodeAnalysis.CSharp.ConvertForEachToFor +{ + [ExportCodeRefactoringProvider(LanguageNames.CSharp, Name = nameof(CSharpConvertForEachToForCodeRefactoringProvider)), Shared] + internal sealed class CSharpConvertForEachToForCodeRefactoringProvider : + AbstractConvertForEachToForCodeRefactoringProvider + { + protected override string Title => CSharpFeaturesResources.Convert_to_for; + + protected override ForEachStatementSyntax GetForEachStatement(TextSpan selection, SyntaxToken token) + { + var foreachStatement = token.Parent.FirstAncestorOrSelf(); + if (foreachStatement == null) + { + return null; + } + + // support refactoring only if caret is in between "foreach" and ")" + var scope = TextSpan.FromBounds(foreachStatement.ForEachKeyword.Span.Start, foreachStatement.CloseParenToken.Span.End); + if (!scope.IntersectsWith(selection)) + { + return null; + } + + // check whether there is any comments between foreach and ) tokens + // if they do, we don't support conversion. + foreach (var trivia in foreachStatement.DescendantTrivia(n => n == foreachStatement || scope.Contains(n.FullSpan))) + { + if (trivia.Span.End <= scope.Start || + scope.End <= trivia.Span.Start) + { + continue; + } + + if (trivia.Kind() != SyntaxKind.WhitespaceTrivia && + trivia.Kind() != SyntaxKind.EndOfLineTrivia) + { + // we don't know what to do with these comments + return null; + } + } + + return foreachStatement; + } + + protected override bool ValidLocation(ForEachInfo foreachInfo) + { + if (!foreachInfo.RequireCollectionStatement) + { + return true; + } + + // for now, we don't support converting in embeded statement if + // new local declaration for collection is required. + // we can support this by using Introduce local variable service + // but the service is not currently written in a way that can be + // easily reused here. + return foreachInfo.ForEachStatement.Parent.IsKind(SyntaxKind.Block); + } + + protected override (SyntaxNode start, SyntaxNode end) GetForEachBody(ForEachStatementSyntax foreachStatement) + => (foreachStatement.Statement, foreachStatement.Statement); + + protected override void ConvertToForStatement( + SemanticModel model, ForEachInfo foreachInfo, SyntaxEditor editor, CancellationToken cancellationToken) + { + cancellationToken.ThrowIfCancellationRequested(); + + var generator = editor.Generator; + var foreachStatement = foreachInfo.ForEachStatement; + + var foreachCollectionExpression = foreachStatement.Expression; + var collectionVariable = GetCollectionVariableName( + model, generator, foreachInfo, foreachCollectionExpression, cancellationToken); + + var collectionStatementType = foreachInfo.RequireExplicitCastInterface + ? generator.GetTypeExpression(foreachInfo.Options, foreachInfo.ExplicitCastInterface) : + generator.GetTypeExpression(foreachInfo.Options, + model.GetTypeInfo(foreachCollectionExpression).Type ?? model.Compilation.GetSpecialType(SpecialType.System_Object)); + + // first, see whether we need to introduce new statement to capture collection + IntroduceCollectionStatement( + model, foreachInfo, editor, collectionStatementType, foreachCollectionExpression, collectionVariable); + + var indexVariable = CreateUniqueName(foreachInfo.SemanticFacts, model, foreachStatement.Statement, "i", cancellationToken); + + // put variable statement in body + var bodyStatement = GetForLoopBody(generator, foreachInfo, collectionVariable, indexVariable); + + // create for statement from foreach statement + var forStatement = SyntaxFactory.ForStatement( + SyntaxFactory.VariableDeclaration( + generator.GetTypeExpression( + foreachInfo.Options, model.Compilation.GetSpecialType(SpecialType.System_Int32)), + SyntaxFactory.SingletonSeparatedList( + SyntaxFactory.VariableDeclarator( + indexVariable.WithAdditionalAnnotations(RenameAnnotation.Create()), + argumentList: default, + SyntaxFactory.EqualsValueClause((ExpressionSyntax)generator.LiteralExpression(0))))), + SyntaxFactory.SeparatedList(), + (ExpressionSyntax)generator.LessThanExpression( + generator.IdentifierName(indexVariable), + generator.MemberAccessExpression(collectionVariable, foreachInfo.CountName)), + SyntaxFactory.SingletonSeparatedList( + SyntaxFactory.PostfixUnaryExpression( + SyntaxKind.PostIncrementExpression, SyntaxFactory.IdentifierName(indexVariable))), + bodyStatement); + + if (!foreachInfo.RequireCollectionStatement) + { + // move comments before "foreach" keyword to "for". if collection statement is introduced, + // it should have attached to the new collection statement, so no need to do it here. + forStatement = forStatement.WithLeadingTrivia(foreachStatement.GetLeadingTrivia()); + } + + // replace close parenthese from "foreach" statement + forStatement = forStatement.WithCloseParenToken(foreachStatement.CloseParenToken); + + editor.ReplaceNode(foreachStatement, forStatement); + } + + private StatementSyntax GetForLoopBody( + SyntaxGenerator generator, ForEachInfo foreachInfo, SyntaxNode collectionVariableName, SyntaxToken indexVariable) + { + var foreachStatement = foreachInfo.ForEachStatement; + if (foreachStatement.Statement is EmptyStatementSyntax) + { + return foreachStatement.Statement; + } + + var bodyBlock = foreachStatement.Statement is BlockSyntax block ? block : SyntaxFactory.Block(foreachStatement.Statement); + if (bodyBlock.Statements.Count > 0) + { + // create variable statement + var variableStatement = AddItemVariableDeclaration( + generator, generator.GetTypeExpression(foreachInfo.Options, foreachInfo.ForEachElementType), + foreachStatement.Identifier, foreachInfo.ForEachElementType, collectionVariableName, indexVariable); + + bodyBlock = bodyBlock.InsertNodesBefore( + bodyBlock.Statements[0], SpecializedCollections.SingletonEnumerable( + variableStatement.WithAdditionalAnnotations(Formatter.Annotation))); + } + + return bodyBlock; + } + } +} diff --git a/src/Features/CSharp/Portable/ConvertForToForEach/CSharpConvertForToForEachCodeRefactoringProvider.cs b/src/Features/CSharp/Portable/ConvertForToForEach/CSharpConvertForToForEachCodeRefactoringProvider.cs index e3c9ae7d41693..156a242cfd06f 100644 --- a/src/Features/CSharp/Portable/ConvertForToForEach/CSharpConvertForToForEachCodeRefactoringProvider.cs +++ b/src/Features/CSharp/Portable/ConvertForToForEach/CSharpConvertForToForEachCodeRefactoringProvider.cs @@ -15,15 +15,15 @@ namespace Microsoft.CodeAnalysis.CSharp.ConvertForToForEach [ExportCodeRefactoringProvider(LanguageNames.CSharp, Name = nameof(CSharpConvertForToForEachCodeRefactoringProvider)), Shared] internal class CSharpConvertForToForEachCodeRefactoringProvider : AbstractConvertForToForEachCodeRefactoringProvider< - StatementSyntax, - ForStatementSyntax, + StatementSyntax, + ForStatementSyntax, ExpressionSyntax, MemberAccessExpressionSyntax, TypeSyntax, VariableDeclaratorSyntax> { protected override string GetTitle() - => CSharpFeaturesResources.Convert_for_to_foreach; + => CSharpFeaturesResources.Convert_to_foreach; protected override bool IsValidCursorPosition(ForStatementSyntax forStatement, int cursorPos) { @@ -44,7 +44,7 @@ protected override SyntaxList GetBodyStatements(ForStatementSyn protected override bool TryGetForStatementComponents( ForStatementSyntax forStatement, out SyntaxToken iterationVariable, out ExpressionSyntax initializer, - out MemberAccessExpressionSyntax memberAccess, + out MemberAccessExpressionSyntax memberAccess, out ExpressionSyntax stepValueExpressionOpt, CancellationToken cancellationToken) { @@ -100,25 +100,25 @@ private static bool TryGetStepValue( ExpressionSyntax operand; switch (incrementor.Kind()) { - case SyntaxKind.PostIncrementExpression: - operand = ((PostfixUnaryExpressionSyntax)incrementor).Operand; - stepValue = default; - break; - - case SyntaxKind.PreIncrementExpression: - operand = ((PrefixUnaryExpressionSyntax)incrementor).Operand; - stepValue = default; - break; - - case SyntaxKind.AddAssignmentExpression: - var assignment = (AssignmentExpressionSyntax)incrementor; - operand = assignment.Left; - stepValue = assignment.Right; - break; - - default: - stepValue = null; - return false; + case SyntaxKind.PostIncrementExpression: + operand = ((PostfixUnaryExpressionSyntax)incrementor).Operand; + stepValue = default; + break; + + case SyntaxKind.PreIncrementExpression: + operand = ((PrefixUnaryExpressionSyntax)incrementor).Operand; + stepValue = default; + break; + + case SyntaxKind.AddAssignmentExpression: + var assignment = (AssignmentExpressionSyntax)incrementor; + operand = assignment.Left; + stepValue = assignment.Right; + break; + + default: + stepValue = null; + return false; } return operand is IdentifierNameSyntax identifierName && @@ -126,24 +126,11 @@ private static bool TryGetStepValue( } protected override SyntaxNode ConvertForNode( - ForStatementSyntax forStatement, TypeSyntax typeNode, + ForStatementSyntax forStatement, TypeSyntax typeNode, SyntaxToken foreachIdentifier, ExpressionSyntax collectionExpression, ITypeSymbol iterationVariableType, OptionSet optionSet) { - if (typeNode == null) - { - // types are not apparent in foreach statements. - var isBuiltInTypeContext = TypeStyleHelper.IsBuiltInType(iterationVariableType); - if (TypeStyleHelper.IsImplicitStylePreferred( - optionSet, isBuiltInTypeContext, isTypeApparentContext: false)) - { - typeNode = SyntaxFactory.IdentifierName("var"); - } - else - { - typeNode = (TypeSyntax)CSharpSyntaxGenerator.Instance.TypeExpression(iterationVariableType); - } - } + typeNode = typeNode ?? CSharpSyntaxGenerator.Instance.GetTypeExpression(optionSet, iterationVariableType); return SyntaxFactory.ForEachStatement( SyntaxFactory.Token(SyntaxKind.ForEachKeyword).WithTriviaFrom(forStatement.ForKeyword), diff --git a/src/Features/CSharp/Portable/ConvertIfToSwitch/CSharpConvertIfToSwitchCodeRefactoringProvider.cs b/src/Features/CSharp/Portable/ConvertIfToSwitch/CSharpConvertIfToSwitchCodeRefactoringProvider.cs index e501566d531b6..bd463feaf7fb3 100644 --- a/src/Features/CSharp/Portable/ConvertIfToSwitch/CSharpConvertIfToSwitchCodeRefactoringProvider.cs +++ b/src/Features/CSharp/Portable/ConvertIfToSwitch/CSharpConvertIfToSwitchCodeRefactoringProvider.cs @@ -25,7 +25,7 @@ public CSharpAnalyzer(ISyntaxFactsService syntaxFacts, SemanticModel semanticMod { } - protected override string Title => CSharpFeaturesResources.Convert_if_to_switch; + protected override string Title => CSharpFeaturesResources.Convert_to_switch; protected override IPattern CreatePatternFromExpression(ExpressionSyntax operand) { diff --git a/src/Features/CSharp/Portable/ConvertLinq/CSharpConvertLinqQueryToForEachProvider.cs b/src/Features/CSharp/Portable/ConvertLinq/CSharpConvertLinqQueryToForEachProvider.cs new file mode 100644 index 0000000000000..ac3c46b13a332 --- /dev/null +++ b/src/Features/CSharp/Portable/ConvertLinq/CSharpConvertLinqQueryToForEachProvider.cs @@ -0,0 +1,978 @@ +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using Microsoft.CodeAnalysis.ConvertLinq; +using Microsoft.CodeAnalysis.CSharp.Extensions; +using Microsoft.CodeAnalysis.CSharp.Symbols; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using Microsoft.CodeAnalysis.Formatting; +using Microsoft.CodeAnalysis.LanguageServices; +using Microsoft.CodeAnalysis.Operations; +using Microsoft.CodeAnalysis.Shared.Extensions; +using Microsoft.CodeAnalysis.Shared.Utilities; +using Microsoft.CodeAnalysis.Simplification; +using Microsoft.CodeAnalysis.Text; + +namespace Microsoft.CodeAnalysis.CSharp.ConvertLinq +{ + internal sealed class CSharpConvertLinqQueryToForEachProvider : AbstractConvertLinqQueryToForEachProvider + { + private static readonly TypeSyntax VarNameIdentifier = SyntaxFactory.IdentifierName("var"); + + protected override string Title => CSharpFeaturesResources.Convert_to_foreach; + + protected override bool TryConvert( + QueryExpressionSyntax queryExpression, + SemanticModel semanticModel, + ISemanticFactsService semanticFacts, + CancellationToken cancellationToken, + out DocumentUpdateInfo documentUpdateInfo) + => new Converter(semanticModel, semanticFacts, queryExpression, cancellationToken).TryConvert(out documentUpdateInfo); + + /// + /// Finds a node for the span and checks that it is either a QueryExpressionSyntax or a QueryExpressionSyntax argument within ArgumentSyntax. + /// + protected override QueryExpressionSyntax FindNodeToRefactor(SyntaxNode root, TextSpan span) + { + var node = root.FindNode(span); + return node as QueryExpressionSyntax ?? (node is ArgumentSyntax argument ? argument.Expression as QueryExpressionSyntax : default); + } + + private sealed class Converter + { + private readonly SemanticModel _semanticModel; + private readonly ISemanticFactsService _semanticFacts; + private readonly CancellationToken _cancellationToken; + private readonly QueryExpressionSyntax _source; + private readonly List _introducedLocalNames; + + public Converter(SemanticModel semanticModel, ISemanticFactsService semanticFacts, QueryExpressionSyntax source, CancellationToken cancellationToken) + { + _semanticModel = semanticModel; + _semanticFacts = semanticFacts; + _source = source; + _introducedLocalNames = new List(); + _cancellationToken = cancellationToken; + } + + public bool TryConvert(out DocumentUpdateInfo documentUpdateInfo) + { + // Do not try refactoring queries with comments or conditional compilation in them. + // We can consider supporting queries with comments in the future. + if (_source.DescendantTrivia().Any(trivia => trivia.MatchesKind( + SyntaxKind.SingleLineCommentTrivia, + SyntaxKind.MultiLineCommentTrivia, + SyntaxKind.MultiLineDocumentationCommentTrivia) || + _source.ContainsDirectives)) + { + documentUpdateInfo = default; + return false; + } + + // Bail out if there is no chance to convert it even with a local function. + if (!CanTryConvertToLocalFunction() || + !TryCreateStackFromQueryExpression(out QueryExpressionProcessingInfo queryExpressionProcessingInfo)) + { + documentUpdateInfo = default; + return false; + } + + // GetDiagnostics is expensive. Move it to the end if there were no bail outs from the algorithm. + // TODO likely adding more semantic checks will perform checks we expect from GetDiagnostics + // We may consider removing GetDiagnostics. + // https://github.com/dotnet/roslyn/issues/25639 + if ((TryConvertInternal(queryExpressionProcessingInfo, out documentUpdateInfo) || + TryReplaceWithLocalFunction(queryExpressionProcessingInfo, out documentUpdateInfo)) && // second attempt: at least to a local function + !_semanticModel.GetDiagnostics(_source.Span, _cancellationToken).Any(diagnostic => diagnostic.DefaultSeverity == DiagnosticSeverity.Error)) + { + if (!documentUpdateInfo.Source.IsParentKind(SyntaxKind.Block) && + documentUpdateInfo.Destinations.Length > 1) + + documentUpdateInfo = new DocumentUpdateInfo(documentUpdateInfo.Source, SyntaxFactory.Block(documentUpdateInfo.Destinations)); + return true; + } + + documentUpdateInfo = default; + return false; + } + + private StatementSyntax ProcessClause( + CSharpSyntaxNode node, + StatementSyntax statement, + bool isLastClause, + bool hasExtraDeclarations, + out StatementSyntax extraStatementToAddAbove) + { + extraStatementToAddAbove = default; + switch (node.Kind()) + { + case SyntaxKind.WhereClause: + return SyntaxFactory.Block(SyntaxFactory.IfStatement(((WhereClauseSyntax)node).Condition.WithAdditionalAnnotations(Simplifier.Annotation).WithoutTrivia(), statement)); + case SyntaxKind.FromClause: + var fromClause = (FromClauseSyntax)node; + + // If we are processing the first from and + // there were joins and some evaluations were moved into declarations above the foreach + // Check if the declaration on the first fromclause should be moved for the evaluation above declarations already moved upfront. + ExpressionSyntax expression1; + if (isLastClause && hasExtraDeclarations && !IsLocalOrParameterSymbol(_source.FromClause.Expression)) + { + string expressionName = _semanticFacts.GenerateNameForExpression( + _semanticModel, + fromClause.Expression, + capitalize: false, + _cancellationToken); + SyntaxToken variable = GetFreeSymbolNameAndMarkUsed(expressionName); + extraStatementToAddAbove = CreateLocalDeclarationStatement(variable, fromClause.Expression, generateTypeFromExpression: false); + expression1 = SyntaxFactory.IdentifierName(variable); + } + else + { + expression1 = fromClause.Expression.WithoutTrivia(); + } + + return SyntaxFactory.ForEachStatement( + fromClause.Type ?? VarNameIdentifier, + fromClause.Identifier, + expression1, + WrapWithBlock(statement)); + case SyntaxKind.LetClause: + var letClause = (LetClauseSyntax)node; + return AddToBlockTop(CreateLocalDeclarationStatement(letClause.Identifier, letClause.Expression, generateTypeFromExpression: false), statement); + case SyntaxKind.JoinClause: + var joinClause = (JoinClauseSyntax)node; + if (joinClause.Into != null) + { + // This must be caught on the validation step. Therefore, here is an exception. + throw new ArgumentException("GroupJoin is not supported"); + } + else + { + ExpressionSyntax expression2; + if (IsLocalOrParameterSymbol(joinClause.InExpression)) + { + expression2 = joinClause.InExpression; + } + else + { + // Input: var q = from x in XX() from z in ZZ() join y in YY() on x equals y select x + y; + // Add + // var xx = XX(); + // var yy = YY(); + // Do not add for ZZ() + string expressionName = _semanticFacts.GenerateNameForExpression( + _semanticModel, + joinClause.InExpression, + capitalize: false, + _cancellationToken); + SyntaxToken variable = GetFreeSymbolNameAndMarkUsed(expressionName); + extraStatementToAddAbove = CreateLocalDeclarationStatement(variable, joinClause.InExpression, generateTypeFromExpression: false); + + // Replace YY() with yy declared above. + expression2 = SyntaxFactory.IdentifierName(variable); + } + + // Output for the join + // var yy == YY(); this goes to extraStatementToAddAbove + // ... + // foreach (var y in yy) + // { + // if (object.Equals(x, y)) + // { + // ... + return SyntaxFactory.Block( + SyntaxFactory.ForEachStatement( + joinClause.Type ?? VarNameIdentifier, + joinClause.Identifier, + expression2, + SyntaxFactory.Block( + SyntaxFactory.IfStatement( + SyntaxFactory.InvocationExpression( + SyntaxFactory.MemberAccessExpression( + SyntaxKind.SimpleMemberAccessExpression, + SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.ObjectKeyword)), + SyntaxFactory.IdentifierName(nameof(object.Equals))), + SyntaxFactory.ArgumentList(SyntaxFactory.SeparatedList( + new[] { + SyntaxFactory.Argument(joinClause.LeftExpression), + SyntaxFactory.Argument(joinClause.RightExpression.WithoutTrailingTrivia())}))), + statement)))).WithAdditionalAnnotations(Simplifier.Annotation); + } + case SyntaxKind.SelectClause: + // This is not the latest Select in the Query Expression + // There is a QueryBody with the Continuation as a parent. + var selectClause = (SelectClauseSyntax)node; + var identifier = ((QueryBodySyntax)selectClause.Parent).Continuation.Identifier; + return AddToBlockTop(CreateLocalDeclarationStatement(identifier, selectClause.Expression, generateTypeFromExpression: true), statement); + default: + throw new ArgumentException($"Unexpected node kind {node.Kind().ToString()}"); + } + } + + private bool TryConvertInternal(QueryExpressionProcessingInfo queryExpressionProcessingInfo, out DocumentUpdateInfo documentUpdateInfo) + { + // (from a in b select a); + SyntaxNode parent = _source.WalkUpParentheses().Parent; + + switch (parent.Kind()) + { + // return from a in b select a; + case SyntaxKind.ReturnStatement: + return TryConvertIfInReturnStatement((ReturnStatementSyntax)parent, queryExpressionProcessingInfo, out documentUpdateInfo); + // foreach(var x in from a in b select a) + case SyntaxKind.ForEachStatement: + return TryConvertIfInForEach((ForEachStatementSyntax)parent, queryExpressionProcessingInfo, out documentUpdateInfo); + // (from a in b select a).ToList(), (from a in b select a).Count(), etc. + case SyntaxKind.SimpleMemberAccessExpression: + return TryConvertIfInMemberAccessExpression((MemberAccessExpressionSyntax)parent, queryExpressionProcessingInfo, out documentUpdateInfo); + } + + documentUpdateInfo = default; + return false; + } + + /// + /// Checks if the location of the query expression allows to convert it at least to a local function. + /// It still does not guarantees that the conversion can be performed. There can be bail outs of later stages. + /// + /// + private bool CanTryConvertToLocalFunction() + { + SyntaxNode currentNode = _source; + while (currentNode != null) + { + if (currentNode is StatementSyntax) { return true; } + if (currentNode is ExpressionSyntax || + currentNode is ArgumentSyntax || + currentNode is ArgumentListSyntax || + currentNode is EqualsValueClauseSyntax || + currentNode is VariableDeclaratorSyntax || + currentNode is VariableDeclarationSyntax) + { + currentNode = currentNode.Parent; + } + else + { + return false; + } + } + + return false; + } + + private bool TryConvertIfInMemberAccessExpression( + MemberAccessExpressionSyntax memberAccessExpression, + QueryExpressionProcessingInfo queryExpressionProcessingInfo, + out DocumentUpdateInfo documentUpdateInfo) + { + if (memberAccessExpression.Parent is InvocationExpressionSyntax invocationExpression) + { + // This also covers generic names (i.e. with type arguments) like 'ToList'. + // The ValueText is still just 'ToList'. + switch (memberAccessExpression.Name.Identifier.ValueText) + { + case nameof(Enumerable.ToList): + return TryConvertIfInToListInvocation(invocationExpression, queryExpressionProcessingInfo, out documentUpdateInfo); + case nameof(Enumerable.Count): + return TryConvertIfInCountInvocation(invocationExpression, queryExpressionProcessingInfo, out documentUpdateInfo); + } + } + + documentUpdateInfo = default; + return false; + } + + private bool TryConvertIfInCountInvocation( + InvocationExpressionSyntax invocationExpression, + QueryExpressionProcessingInfo queryExpressionProcessingInfo, + out DocumentUpdateInfo documentUpdateInfo) + { + if (_semanticModel.GetSymbolInfo(invocationExpression, _cancellationToken).Symbol is IMethodSymbol methodSymbol && + methodSymbol.Parameters.Length == 0 && + methodSymbol.ReturnType?.SpecialType == SpecialType.System_Int32 && + methodSymbol.RefKind == RefKind.None) + { + // before var count = (from a in b select a).Count(); + // after + // var count = 0; + // foreach (var a in b) + // { + // count++; + // } + return TryConvertIfInInvocation( + invocationExpression, + queryExpressionProcessingInfo, + IsInt, + (variableIdentifier, expression) => SyntaxFactory.ExpressionStatement( + SyntaxFactory.PostfixUnaryExpression(SyntaxKind.PostIncrementExpression, variableIdentifier)), // Generating 'count++' + SyntaxFactory.LiteralExpression(SyntaxKind.NumericLiteralExpression, SyntaxFactory.Literal(0)), // count = 0 + variableName: "count", + out documentUpdateInfo); + } + + documentUpdateInfo = default; + return false; + } + + private bool TryConvertIfInToListInvocation( + InvocationExpressionSyntax invocationExpression, + QueryExpressionProcessingInfo queryExpressionProcessingInfo, + out DocumentUpdateInfo documentUpdateInfo) + { + // before var list = (from a in b select a).ToList(); + // after + // var list = new List(); + // foreach (var a in b) + // { + // list.Add(a) + // } + if (_semanticModel.GetSymbolInfo(invocationExpression, _cancellationToken).Symbol is IMethodSymbol methodSymbol && + methodSymbol.RefKind == RefKind.None && + IsList(methodSymbol.ReturnType) && + methodSymbol.Parameters.Length == 0) + { + return TryConvertIfInInvocation( + invocationExpression, + queryExpressionProcessingInfo, + IsList, + (listIdentifier, expression) => SyntaxFactory.ExpressionStatement(SyntaxFactory.InvocationExpression( + SyntaxFactory.MemberAccessExpression( + SyntaxKind.SimpleMemberAccessExpression, + listIdentifier, + SyntaxFactory.IdentifierName(nameof(IList.Add))), + SyntaxFactory.ArgumentList(SyntaxFactory.SingletonSeparatedList(SyntaxFactory.Argument(expression))))), + SyntaxFactory.ObjectCreationExpression( + methodSymbol.GenerateReturnTypeSyntax().WithAdditionalAnnotations(Simplifier.Annotation), + SyntaxFactory.ArgumentList(), + initializer: null), + variableName: "list", + out documentUpdateInfo); + } + + documentUpdateInfo = default; + return false; + } + + private bool IsInt(ITypeSymbol typeSymbol) + => typeSymbol.SpecialType == SpecialType.System_Int32; + + private bool IsList(ITypeSymbol typeSymbol) + => Equals(typeSymbol.OriginalDefinition, _semanticModel.Compilation.GetTypeByMetadataName(typeof(List<>).FullName)); + + private bool TryConvertIfInInvocation( + InvocationExpressionSyntax invocationExpression, + QueryExpressionProcessingInfo queryExpressionProcessingInfo, + Func typeCheckMethod, + Func leafExpressionCreationMethod, + ExpressionSyntax initializer, + string variableName, + out DocumentUpdateInfo documentUpdateInfo) + { + var parentStatement = invocationExpression.GetAncestorOrThis(); + if (parentStatement != null) + { + if (TryConvertIfInInvocationInternal( + invocationExpression, + typeCheckMethod, + parentStatement, + initializer, + variableName, + out var variable, + out var nodesBefore, + out var nodesAfter)) + { + var statements = GenerateStatements(expression => leafExpressionCreationMethod(variable, expression), queryExpressionProcessingInfo); + var list = new List(); + list.AddRange(nodesBefore); + list.AddRange(statements); + list.AddRange(nodesAfter); + documentUpdateInfo = new DocumentUpdateInfo(parentStatement, list); + return true; + } + } + + documentUpdateInfo = default; + return false; + } + + private bool TryConvertIfInInvocationInternal( + InvocationExpressionSyntax invocationExpression, + Func typeCheckMethod, + StatementSyntax parentStatement, + ExpressionSyntax initializer, + string variableName, + out ExpressionSyntax variable, + out StatementSyntax[] nodesBefore, + out StatementSyntax[] nodesAfter) + { + var invocationParent = invocationExpression.WalkUpParentheses().Parent; + var symbolName = GetFreeSymbolNameAndMarkUsed(variableName); + + void Convert( + ExpressionSyntax variableExpression, + ExpressionSyntax expressionToVerifyType, + bool checkForLocalOrParameter, + out ExpressionSyntax variableLocal, + out StatementSyntax[] nodesBeforeLocal, + out StatementSyntax[] nodesAfterLocal) + { + // Check that we can re-use the local variable or parameter + if (typeCheckMethod(_semanticModel.GetTypeInfo(expressionToVerifyType, _cancellationToken).Type) && + (!checkForLocalOrParameter || IsLocalOrParameterSymbol(variableExpression))) + { + // before + // a = (from a in b select a).ToList(); or var a = (from a in b select a).ToList() + // after + // a = new List(); or var a = new List(); + // foreach(...) + variableLocal = variableExpression; + nodesBeforeLocal = new[] { parentStatement.ReplaceNode(invocationExpression, initializer.WithAdditionalAnnotations(Simplifier.Annotation)) }; + nodesAfterLocal = new StatementSyntax[] { }; + } + else + { + // before + // IReadOnlyList a = (from a in b select a).ToList(); or an assignment + // after + // var list = new List(); or assignment + // foreach(...) + // IReadOnlyList a = list; + variableLocal = SyntaxFactory.IdentifierName(symbolName); + nodesBeforeLocal = new[] { CreateLocalDeclarationStatement(symbolName, initializer, generateTypeFromExpression: false) }; + nodesAfterLocal = new StatementSyntax[] { parentStatement.ReplaceNode(invocationExpression, variableLocal.WithAdditionalAnnotations(Simplifier.Annotation)) }; + } + } + + switch (invocationParent.Kind()) + { + case SyntaxKind.EqualsValueClause: + // Avoid for(int i = (from x in a select x).Count(); i < 10; i++) + if (invocationParent.IsParentKind(SyntaxKind.VariableDeclarator, SyntaxKind.VariableDeclaration, SyntaxKind.LocalDeclarationStatement) && + // Avoid int i = (from x in a select x).Count(), j = i; + ((VariableDeclarationSyntax)invocationParent.Parent.Parent).Variables.Count == 1) + { + var variableDeclarator = ((VariableDeclaratorSyntax)invocationParent.Parent); + Convert( + SyntaxFactory.IdentifierName(variableDeclarator.Identifier), + ((VariableDeclarationSyntax)variableDeclarator.Parent).Type, + checkForLocalOrParameter: false, + out variable, + out nodesBefore, + out nodesAfter); + return true; + } + + break; + case SyntaxKind.SimpleAssignmentExpression: + var assignmentExpression = (AssignmentExpressionSyntax)invocationParent; + if (assignmentExpression.Right.WalkDownParentheses() == invocationExpression) + { + Convert( + assignmentExpression.Left, + assignmentExpression.Left, + checkForLocalOrParameter: true, + out variable, + out nodesBefore, + out nodesAfter); + return true; + } + + break; + case SyntaxKind.ReturnStatement: + // before return (from a in b select a).ToList(); + // after var list = new List(); + // foreach(...) + // return list; + variable = SyntaxFactory.IdentifierName(symbolName); + nodesBefore = new[] { CreateLocalDeclarationStatement(symbolName, initializer, generateTypeFromExpression: false) }; + nodesAfter = new[] { SyntaxFactory.ReturnStatement(variable).WithAdditionalAnnotations(Simplifier.Annotation) }; + return true; + // SyntaxKind.Argument: + // SyntaxKind.ArrowExpressionClause is not supported + } + + // Will still try to replace with a local function above. + nodesBefore = default; + nodesAfter = default; + variable = default; + return false; + } + + private LocalDeclarationStatementSyntax CreateLocalDeclarationStatement( + SyntaxToken identifier, + ExpressionSyntax expression, + bool generateTypeFromExpression) + { + var typeSyntax = generateTypeFromExpression ? + _semanticModel.GetTypeInfo(expression, _cancellationToken).ConvertedType.GenerateTypeSyntax() : + VarNameIdentifier; + return SyntaxFactory.LocalDeclarationStatement( + SyntaxFactory.VariableDeclaration( + typeSyntax, + SyntaxFactory.SingletonSeparatedList( + SyntaxFactory.VariableDeclarator( + identifier, + argumentList: null, + SyntaxFactory.EqualsValueClause(expression))))).WithAdditionalAnnotations(Simplifier.Annotation); + } + + private bool TryReplaceWithLocalFunction(QueryExpressionProcessingInfo queryExpressionProcessingInfo, out DocumentUpdateInfo documentUpdateInfo) + { + var parentStatement = _source.GetAncestorOrThis(); + if (parentStatement == null) + { + documentUpdateInfo = default; + return false; + } + + // before statement ... from a in select b ... + // after + // IEnumerable localFunction() + // { + // foreach(var a in b) + // { + // yield return a; + // } + // } + // statement ... localFunction(); + var returnTypeInfo = _semanticModel.GetTypeInfo(_source, _cancellationToken); + ITypeSymbol returnedType; + + if (returnTypeInfo.Type.OriginalDefinition?.SpecialType == SpecialType.System_Collections_Generic_IEnumerable_T) + { + returnedType = returnTypeInfo.Type; + } + else + { + if (returnTypeInfo.ConvertedType.OriginalDefinition?.SpecialType == SpecialType.System_Collections_Generic_IEnumerable_T) + { + returnedType = returnTypeInfo.ConvertedType; + } + else + { + documentUpdateInfo = default; + return false; + } + } + + StatementSyntax internalNodeMethod(ExpressionSyntax expression) + => SyntaxFactory.YieldStatement(SyntaxKind.YieldReturnStatement, expression); + + var statements = GenerateStatements(internalNodeMethod, queryExpressionProcessingInfo); + string localFunctionNamePrefix = _semanticFacts.GenerateNameForExpression( + _semanticModel, + _source, + capitalize: false, + _cancellationToken); + SyntaxToken localFunctionToken = GetFreeSymbolNameAndMarkUsed(localFunctionNamePrefix); + var localFunctionDeclaration = SyntaxFactory.LocalFunctionStatement( + modifiers: default, + returnType: returnedType.GenerateTypeSyntax().WithAdditionalAnnotations(Simplifier.Annotation), + identifier: localFunctionToken, + typeParameterList: null, + parameterList: SyntaxFactory.ParameterList(), + constraintClauses: default, + body: SyntaxFactory.Block( + SyntaxFactory.Token( + SyntaxFactory.TriviaList(), + SyntaxKind.OpenBraceToken, + SyntaxFactory.TriviaList(SyntaxFactory.EndOfLine(Environment.NewLine))), + SyntaxFactory.List(statements), + SyntaxFactory.Token(SyntaxKind.CloseBraceToken)), + expressionBody: null); + + var localFunctionInvocation = SyntaxFactory.InvocationExpression(SyntaxFactory.IdentifierName(localFunctionToken)).WithAdditionalAnnotations(Simplifier.Annotation); + StatementSyntax newParentExpressionStatement = parentStatement.ReplaceNode(_source.WalkUpParentheses(), localFunctionInvocation.WithAdditionalAnnotations(Simplifier.Annotation)); + documentUpdateInfo = new DocumentUpdateInfo(parentStatement, new[] { localFunctionDeclaration, newParentExpressionStatement }); + return true; + } + + private SyntaxToken GetFreeSymbolNameAndMarkUsed(string prefix) + { + var freeToken = _semanticFacts.GenerateUniqueName(_semanticModel, _source, containerOpt: null, baseName: prefix, _introducedLocalNames, _cancellationToken); + _introducedLocalNames.Add(freeToken.ValueText); + return freeToken; + } + + private bool TryConvertIfInForEach( + ForEachStatementSyntax forEachStatement, + QueryExpressionProcessingInfo queryExpressionProcessingInfo, + out DocumentUpdateInfo documentUpdateInfo) + { + // before foreach(var x in from a in b select a) + + if (forEachStatement.Expression.WalkDownParentheses() != _source) + { + documentUpdateInfo = default; + return false; + } + + // check that the body of the forEach does not contain any identifiers from the query + foreach (var identifierName in queryExpressionProcessingInfo.IdentifierNames) + { + // Identifier from the foreach can already be in scope of the foreach statement. + if (forEachStatement.Identifier.ValueText != identifierName) + { + if (_semanticFacts.GenerateUniqueName( + _semanticModel, + location: forEachStatement.Statement, + containerOpt: forEachStatement.Statement, + baseName: identifierName, + usedNames: Enumerable.Empty(), + _cancellationToken).ValueText != identifierName) + { + documentUpdateInfo = default; + return false; + } + } + } + + // If query does not contains identifier with the same name as declared in the foreach, + // declare this identifier in the body. + if (!queryExpressionProcessingInfo.ContainsIdentifier(forEachStatement.Identifier)) + { + documentUpdateInfo = ConvertIfInToForeachWithExtraVariableDeclaration(forEachStatement, queryExpressionProcessingInfo); + return true; + } + else + { + // The last select expression in the query returns this identifier: + // foreach(var thisIdentifier in from ....... select thisIdentifier) + // if thisIdentifier in foreach is var, it is OK + // if a type is specified for thisIdentifier in forEach, check that the type is the same as in the select expression + // foreach(MyType thisIdentifier in from ....... from MyType thisIdentifier ... select thisIdentifier) + + // The last clause in query stack must be SelectClauseSyntax. + var lastSelectExpression = ((SelectClauseSyntax)queryExpressionProcessingInfo.Stack.Peek()).Expression; + if (lastSelectExpression is IdentifierNameSyntax identifierName && + forEachStatement.Identifier.ValueText == identifierName.Identifier.ValueText && + queryExpressionProcessingInfo.IdentifierNames.Contains(identifierName.Identifier.ValueText)) + { + var forEachStatementTypeSymbolType = _semanticModel.GetTypeInfo(forEachStatement.Type, _cancellationToken).Type; + var lastSelectExpressionTypeInfo = _semanticModel.GetTypeInfo(lastSelectExpression, _cancellationToken); + if (Equals(lastSelectExpressionTypeInfo.ConvertedType, lastSelectExpressionTypeInfo.Type) && + Equals(lastSelectExpressionTypeInfo.ConvertedType, forEachStatementTypeSymbolType)) + { + documentUpdateInfo = ConvertIfInToForeachWithoutExtraVariableDeclaration(forEachStatement, queryExpressionProcessingInfo); + return true; + } + } + } + + // in all other cases try to replace with a local function - this is called above. + documentUpdateInfo = default; + return false; + } + + private DocumentUpdateInfo ConvertIfInToForeachWithExtraVariableDeclaration( + ForEachStatementSyntax forEachStatement, + QueryExpressionProcessingInfo queryExpressionProcessingInfo) + { + // before foreach(var x in from ... a) { dosomething(x); } + // after + // foreach (var a in ...) + // ... + // { + // var x = a; + // dosomething(x); + // } + var statements = GenerateStatements( + expression => AddToBlockTop(SyntaxFactory.LocalDeclarationStatement( + SyntaxFactory.VariableDeclaration( + forEachStatement.Type, + SyntaxFactory.SingletonSeparatedList( + SyntaxFactory.VariableDeclarator( + forEachStatement.Identifier, + argumentList: null, + SyntaxFactory.EqualsValueClause(expression))))), + forEachStatement.Statement).WithAdditionalAnnotations(Formatter.Annotation), queryExpressionProcessingInfo); + return new DocumentUpdateInfo(forEachStatement, statements); + } + + private DocumentUpdateInfo ConvertIfInToForeachWithoutExtraVariableDeclaration( + ForEachStatementSyntax forEachStatement, + QueryExpressionProcessingInfo queryExpressionProcessingInfo) + { + // before + // foreach (var a in from a in b where a > 5 select a) + // { + // dosomething(a); + // } + // after + // foreach (var a in b) + // { + // if (a > 5) + // { + // dosomething(a); + // } + // } + var statements = GenerateStatements( + expression => forEachStatement.Statement.WithAdditionalAnnotations(Formatter.Annotation), + queryExpressionProcessingInfo); + return new DocumentUpdateInfo(forEachStatement, statements); + } + + private bool TryConvertIfInReturnStatement( + ReturnStatementSyntax returnStatement, + QueryExpressionProcessingInfo queryExpressionProcessingInfo, + out DocumentUpdateInfo documentUpdateInfo) + { + // The conversion requires yield return which cannot be added to lambdas and anonymous method declarations. + if (IsWithinImmediateLambdaOrAnonymousMethod(returnStatement)) + { + documentUpdateInfo = default; + return false; + } + + var memberDeclarationNode = FindParentMemberDeclarationNode(returnStatement, out var declaredSymbol); + if (!(declaredSymbol is IMethodSymbol methodSymbol)) + { + documentUpdateInfo = default; + return false; + } + + if (methodSymbol.ReturnType.OriginalDefinition?.SpecialType != SpecialType.System_Collections_Generic_IEnumerable_T) + { + documentUpdateInfo = default; + return false; + } + + // if there are more than one return in the method, convert to local funciton. + if (memberDeclarationNode.DescendantNodes().OfType().Count() == 1) + { + // before: return from a in b select a; + // after: + // foreach(var a in b) + // { + // yield return a; + // } + // + // yield break; + var statements = GenerateStatements((ExpressionSyntax expression) + => SyntaxFactory.YieldStatement(SyntaxKind.YieldReturnStatement, expression), queryExpressionProcessingInfo); + + // add an yield break to avoid throws after the return. + var yieldBreakStatement = SyntaxFactory.YieldStatement(SyntaxKind.YieldBreakStatement); + documentUpdateInfo = new DocumentUpdateInfo(returnStatement, statements.Concat(new[] { yieldBreakStatement })); + return true; + } + + documentUpdateInfo = default; + return false; + } + + // We may assume that the query is defined within a method, field, property and so on and it is declare just once. + private SyntaxNode FindParentMemberDeclarationNode(SyntaxNode node, out ISymbol declaredSymbol) + { + declaredSymbol = _semanticModel.GetEnclosingSymbol(node.SpanStart, _cancellationToken); + return declaredSymbol.DeclaringSyntaxReferences.Single().GetSyntax(); + } + + private bool TryCreateStackFromQueryExpression(out QueryExpressionProcessingInfo queryExpressionProcessingInfo) + { + queryExpressionProcessingInfo = new QueryExpressionProcessingInfo(_source.FromClause); + return TryProcessQueryBody(_source.Body, queryExpressionProcessingInfo); + } + + private StatementSyntax[] GenerateStatements( + Func leafExpressionCreationMethod, + QueryExpressionProcessingInfo queryExpressionProcessingInfo) + { + StatementSyntax statement = default; + var stack = queryExpressionProcessingInfo.Stack; + // Executes syntax building methods from bottom to the top of the tree. + // Process last clause + if (stack.Any()) + { + var node = stack.Pop(); + if (node is SelectClauseSyntax selectClause) + { + statement = WrapWithBlock(leafExpressionCreationMethod(selectClause.Expression)); + } + else + { + throw new ArgumentException("Last node must me the select clause"); + } + } + + // Process all other clauses + List statements = new List(); + while (stack.Any()) + { + statement = ProcessClause( + stack.Pop(), + statement, + isLastClause: !stack.Any(), + hasExtraDeclarations: statements.Any(), + out StatementSyntax extraStatement); + if (extraStatement != null) + { + statements.Add(extraStatement); + } + } + + // The stack was processed in the reverse order, but the extra statements should be provided in the direct order. + statements.Reverse(); + statements.Add(statement.WithAdditionalAnnotations(Simplifier.Annotation)); + return statements.ToArray(); + } + + private bool TryProcessQueryBody(QueryBodySyntax queryBody, QueryExpressionProcessingInfo queryExpressionProcessingInfo) + { + do + { + foreach (var queryClause in queryBody.Clauses) + { + switch (queryClause.Kind()) + { + case SyntaxKind.WhereClause: + queryExpressionProcessingInfo.Add(queryClause); + break; + case SyntaxKind.LetClause: + if (!queryExpressionProcessingInfo.TryAdd(queryClause, ((LetClauseSyntax)queryClause).Identifier)) + { + return false; + } + + break; + case SyntaxKind.FromClause: + var fromClause = (FromClauseSyntax)queryClause; + if (!queryExpressionProcessingInfo.TryAdd(queryClause, fromClause.Identifier)) + { + return false; + } + + break; + case SyntaxKind.JoinClause: + var joinClause = (JoinClauseSyntax)queryClause; + if (joinClause.Into == null) // GroupJoin is not supported + { + if (queryExpressionProcessingInfo.TryAdd(joinClause, joinClause.Identifier)) + { + break; + } + } + + return false; + // OrderBy is not supported by foreach. + default: + return false; + } + } + + // GroupClause is not supported by the conversion + if (!(queryBody.SelectOrGroup is SelectClauseSyntax selectClause)) + { + return false; + } + + if (_semanticModel.GetTypeInfo(selectClause.Expression, _cancellationToken).Type.ContainsAnonymousType()) + { + return false; + } + + queryExpressionProcessingInfo.Add(selectClause); + queryBody = queryBody.Continuation?.Body; + } while (queryBody != null); + + return true; + } + + private static BlockSyntax AddToBlockTop(StatementSyntax newStatement, StatementSyntax statement) + { + if (statement is BlockSyntax block) + { + return block.WithStatements(block.Statements.Insert(0, newStatement)); + } + else + { + return SyntaxFactory.Block(newStatement, statement); + } + } + + private bool IsLocalOrParameterSymbol(ExpressionSyntax expression) + => IsLocalOrParameterSymbol(_semanticModel.GetOperation(expression, _cancellationToken)); + + private static bool IsLocalOrParameterSymbol(IOperation operation) + { + if (operation is IConversionOperation conversion && conversion.IsImplicit) + { + return IsLocalOrParameterSymbol(conversion.Operand); + } + + return operation.Kind == OperationKind.LocalReference || operation.Kind == OperationKind.ParameterReference; + } + + private static BlockSyntax WrapWithBlock(StatementSyntax statement) + => statement is BlockSyntax block ? block : SyntaxFactory.Block(statement); + + // Checks if the node is within an immediate lambda or within an immediate anonymous method. + // 'lambda => node' returns true + // 'lambda => localfunction => node' returns false + // 'member => node' returns false + private static bool IsWithinImmediateLambdaOrAnonymousMethod(SyntaxNode node) + { + while (node != null) + { + switch (node.Kind()) + { + case SyntaxKind.AnonymousMethodExpression: + case SyntaxKind.ParenthesizedLambdaExpression: + case SyntaxKind.SimpleLambdaExpression: + return true; + case SyntaxKind.LocalFunctionStatement: + return false; + default: + if (node is MemberDeclarationSyntax) + { + return false; + } + + break; + } + + node = node.Parent; + } + + return false; + } + + private class QueryExpressionProcessingInfo + { + public Stack Stack { get; private set; } + + public HashSet IdentifierNames { get; private set; } + + public QueryExpressionProcessingInfo(FromClauseSyntax fromClause) + { + Stack = new Stack(); + Stack.Push(fromClause); + IdentifierNames = new HashSet(); + IdentifierNames.Add((fromClause.Identifier.ValueText)); + } + + public bool TryAdd(CSharpSyntaxNode node, SyntaxToken identifier) + { + // Duplicate identifiers are not allowed. + // var q = from x in new[] { 1 } select x + 2 into x where x > 0 select 7 into y let x = ""aaa"" select x; + if (!IdentifierNames.Add(identifier.ValueText)) + { + return false; + } + + Stack.Push(node); + return true; + } + + public void Add(CSharpSyntaxNode node) => Stack.Push(node); + + public bool ContainsIdentifier(SyntaxToken identifier) + => IdentifierNames.Contains(identifier.ValueText); + } + } + } +} diff --git a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.cs.xlf b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.cs.xlf index 29bced5fd8c77..f8761d71a9d41 100644 --- a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.cs.xlf +++ b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.cs.xlf @@ -592,11 +592,6 @@ Přidejte položku this. - - Convert 'if' to 'switch' - Převést if na switch - - Warning: Extracting a local function reference may produce invalid code Upozornění: Extrahování odkazu na místní funkci může vytvořit neplatný kód. @@ -632,9 +627,19 @@ Add parentheses - - Convert 'for' to 'foreach' - Convert 'for' to 'foreach' + + Convert to 'switch' + Convert to 'switch' + + + + Convert to 'foreach' + Convert to 'foreach' + + + + Convert to 'for' + Convert to 'for' diff --git a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.de.xlf b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.de.xlf index 816e56f71e30a..32411ec4fc6a6 100644 --- a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.de.xlf +++ b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.de.xlf @@ -592,11 +592,6 @@ "this." hinzufügen - - Convert 'if' to 'switch' - "if" in "switch" konvertieren - - Warning: Extracting a local function reference may produce invalid code Warnung: Das Extrahieren eines lokalen Funktionsverweises führt unter Umständen zu ungültigem Code. @@ -632,9 +627,19 @@ Add parentheses - - Convert 'for' to 'foreach' - Convert 'for' to 'foreach' + + Convert to 'switch' + Convert to 'switch' + + + + Convert to 'foreach' + Convert to 'foreach' + + + + Convert to 'for' + Convert to 'for' diff --git a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.es.xlf b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.es.xlf index 0c4e303d3ecef..ab75cbb73bd4d 100644 --- a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.es.xlf +++ b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.es.xlf @@ -592,11 +592,6 @@ Agregar "this." - - Convert 'if' to 'switch' - Convertir "if" en "switch" - - Warning: Extracting a local function reference may produce invalid code Advertencia: Extraer una referencia a una función local puede generar código no válido. @@ -632,9 +627,19 @@ Add parentheses - - Convert 'for' to 'foreach' - Convert 'for' to 'foreach' + + Convert to 'switch' + Convert to 'switch' + + + + Convert to 'foreach' + Convert to 'foreach' + + + + Convert to 'for' + Convert to 'for' diff --git a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.fr.xlf b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.fr.xlf index 240e5d0e6b1f3..03ea42f302e91 100644 --- a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.fr.xlf +++ b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.fr.xlf @@ -592,11 +592,6 @@ Ajouter 'this.' - - Convert 'if' to 'switch' - Convertir 'if' en 'switch' - - Warning: Extracting a local function reference may produce invalid code Avertissement : L'extraction d'une référence de fonction locale peut produire du code non valide @@ -632,9 +627,19 @@ Add parentheses - - Convert 'for' to 'foreach' - Convert 'for' to 'foreach' + + Convert to 'switch' + Convert to 'switch' + + + + Convert to 'foreach' + Convert to 'foreach' + + + + Convert to 'for' + Convert to 'for' diff --git a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.it.xlf b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.it.xlf index b706846a51315..767ba00660194 100644 --- a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.it.xlf +++ b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.it.xlf @@ -592,11 +592,6 @@ Aggiungi 'this.' - - Convert 'if' to 'switch' - Converti 'if' in 'switch' - - Warning: Extracting a local function reference may produce invalid code Avviso: il codice prodotto in seguito all'estrazione di un riferimento a una funzione locale potrebbe non essere valido @@ -632,9 +627,19 @@ Add parentheses - - Convert 'for' to 'foreach' - Convert 'for' to 'foreach' + + Convert to 'switch' + Convert to 'switch' + + + + Convert to 'foreach' + Convert to 'foreach' + + + + Convert to 'for' + Convert to 'for' diff --git a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.ja.xlf b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.ja.xlf index 89c778ea2fac5..3d40a2169b5a7 100644 --- a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.ja.xlf +++ b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.ja.xlf @@ -592,11 +592,6 @@ this' を追加します。 - - Convert 'if' to 'switch' - if' を 'switch' に変換 - - Warning: Extracting a local function reference may produce invalid code 警告: ローカル関数参照を抽出すると無効なコードが生成される可能性があります @@ -632,9 +627,19 @@ Add parentheses - - Convert 'for' to 'foreach' - Convert 'for' to 'foreach' + + Convert to 'switch' + Convert to 'switch' + + + + Convert to 'foreach' + Convert to 'foreach' + + + + Convert to 'for' + Convert to 'for' diff --git a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.ko.xlf b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.ko.xlf index ce36327089730..341cd5e07858a 100644 --- a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.ko.xlf +++ b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.ko.xlf @@ -592,11 +592,6 @@ this'를 추가합니다. - - Convert 'if' to 'switch' - if'를 'switch'로 변환 - - Warning: Extracting a local function reference may produce invalid code 경고: 로컬 함수 참조를 추출하면 잘못된 코드가 생성될 수 있습니다. @@ -632,9 +627,19 @@ Add parentheses - - Convert 'for' to 'foreach' - Convert 'for' to 'foreach' + + Convert to 'switch' + Convert to 'switch' + + + + Convert to 'foreach' + Convert to 'foreach' + + + + Convert to 'for' + Convert to 'for' diff --git a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.pl.xlf b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.pl.xlf index 4e92fea5ca8a4..30e151bfa70e5 100644 --- a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.pl.xlf +++ b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.pl.xlf @@ -592,11 +592,6 @@ Dodaj „this.” - - Convert 'if' to 'switch' - Konwertuj „if” na „switch” - - Warning: Extracting a local function reference may produce invalid code Ostrzeżenie: Wyodrębnienie odwołania do funkcji lokalnej może skutkować powstaniem nieprawidłowego kodu @@ -632,9 +627,19 @@ Add parentheses - - Convert 'for' to 'foreach' - Convert 'for' to 'foreach' + + Convert to 'switch' + Convert to 'switch' + + + + Convert to 'foreach' + Convert to 'foreach' + + + + Convert to 'for' + Convert to 'for' diff --git a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.pt-BR.xlf b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.pt-BR.xlf index e36ded1ea3540..f2e5bd3ed4aa7 100644 --- a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.pt-BR.xlf +++ b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.pt-BR.xlf @@ -592,11 +592,6 @@ Adicionar 'isso.' - - Convert 'if' to 'switch' - Converter 'if' em 'switch' - - Warning: Extracting a local function reference may produce invalid code Aviso: a extração de uma referência de função local pode produzir um código inválido @@ -632,9 +627,19 @@ Add parentheses - - Convert 'for' to 'foreach' - Convert 'for' to 'foreach' + + Convert to 'switch' + Convert to 'switch' + + + + Convert to 'foreach' + Convert to 'foreach' + + + + Convert to 'for' + Convert to 'for' diff --git a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.ru.xlf b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.ru.xlf index 222e98d821474..50b203cf632df 100644 --- a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.ru.xlf +++ b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.ru.xlf @@ -592,11 +592,6 @@ Добавьте "this". - - Convert 'if' to 'switch' - Преобразовать if в switch - - Warning: Extracting a local function reference may produce invalid code Внимание! Извлечение ссылки на локальную функцию может привести к созданию недопустимого кода. @@ -632,9 +627,19 @@ Add parentheses - - Convert 'for' to 'foreach' - Convert 'for' to 'foreach' + + Convert to 'switch' + Convert to 'switch' + + + + Convert to 'foreach' + Convert to 'foreach' + + + + Convert to 'for' + Convert to 'for' diff --git a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.tr.xlf b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.tr.xlf index 7fce96ed8937c..575fe250f0fbc 100644 --- a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.tr.xlf +++ b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.tr.xlf @@ -592,11 +592,6 @@ this' ekleyin. - - Convert 'if' to 'switch' - if' deyimini 'switch' deyimine dönüştür - - Warning: Extracting a local function reference may produce invalid code Uyarı: Bir yerel işlev referansının ayıklanması geçersiz kod oluşturulmasına neden olabilir @@ -632,9 +627,19 @@ Add parentheses - - Convert 'for' to 'foreach' - Convert 'for' to 'foreach' + + Convert to 'switch' + Convert to 'switch' + + + + Convert to 'foreach' + Convert to 'foreach' + + + + Convert to 'for' + Convert to 'for' diff --git a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.zh-Hans.xlf b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.zh-Hans.xlf index f87725b8f0685..05c36f2a656ac 100644 --- a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.zh-Hans.xlf +++ b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.zh-Hans.xlf @@ -592,11 +592,6 @@ 添加 "this." - - Convert 'if' to 'switch' - 将 "if" 转换为 "switch" - - Warning: Extracting a local function reference may produce invalid code 警告: 提取本地函数引用可能会生成无效代码 @@ -632,9 +627,19 @@ Add parentheses - - Convert 'for' to 'foreach' - Convert 'for' to 'foreach' + + Convert to 'switch' + Convert to 'switch' + + + + Convert to 'foreach' + Convert to 'foreach' + + + + Convert to 'for' + Convert to 'for' diff --git a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.zh-Hant.xlf b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.zh-Hant.xlf index 28c28b1e4ac15..ff4ec49a7202a 100644 --- a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.zh-Hant.xlf +++ b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.zh-Hant.xlf @@ -592,11 +592,6 @@ 新增 'this.' - - Convert 'if' to 'switch' - 將 'if' 轉換為 'switch' - - Warning: Extracting a local function reference may produce invalid code 警告: 擷取本機函式參考可能會產生無效的程式碼 @@ -632,9 +627,19 @@ Add parentheses - - Convert 'for' to 'foreach' - Convert 'for' to 'foreach' + + Convert to 'switch' + Convert to 'switch' + + + + Convert to 'foreach' + Convert to 'foreach' + + + + Convert to 'for' + Convert to 'for' diff --git a/src/Features/Core/Portable/ConvertForEachToFor/AbstractConvertForEachToForCodeRefactoringProvider.cs b/src/Features/Core/Portable/ConvertForEachToFor/AbstractConvertForEachToForCodeRefactoringProvider.cs new file mode 100644 index 0000000000000..348055ffcc257 --- /dev/null +++ b/src/Features/Core/Portable/ConvertForEachToFor/AbstractConvertForEachToForCodeRefactoringProvider.cs @@ -0,0 +1,474 @@ +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.CodeAnalysis.CodeActions; +using Microsoft.CodeAnalysis.CodeRefactorings; +using Microsoft.CodeAnalysis.Editing; +using Microsoft.CodeAnalysis.Formatting; +using Microsoft.CodeAnalysis.LanguageServices; +using Microsoft.CodeAnalysis.Operations; +using Microsoft.CodeAnalysis.Options; +using Microsoft.CodeAnalysis.Shared.Extensions; +using Microsoft.CodeAnalysis.Simplification; +using Microsoft.CodeAnalysis.Text; +using Roslyn.Utilities; + +namespace Microsoft.CodeAnalysis.ConvertForEachToFor +{ + internal abstract class AbstractConvertForEachToForCodeRefactoringProvider : + CodeRefactoringProvider + where TForEachStatement : SyntaxNode + { + private const string get_Count = nameof(get_Count); + private const string get_Item = nameof(get_Item); + + private const string Length = nameof(Array.Length); + private const string Count = nameof(IList.Count); + + private static readonly ImmutableArray s_KnownInterfaceNames = + ImmutableArray.Create(typeof(IList<>).FullName, typeof(IReadOnlyList<>).FullName, typeof(IList).FullName); + + protected abstract string Title { get; } + protected abstract TForEachStatement GetForEachStatement(TextSpan selelction, SyntaxToken token); + protected abstract bool ValidLocation(ForEachInfo foreachInfo); + protected abstract (SyntaxNode start, SyntaxNode end) GetForEachBody(TForEachStatement foreachStatement); + protected abstract void ConvertToForStatement( + SemanticModel model, ForEachInfo info, SyntaxEditor editor, CancellationToken cancellationToken); + + public override async Task ComputeRefactoringsAsync(CodeRefactoringContext context) + { + var document = context.Document; + var cancellationToken = context.CancellationToken; + + var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); + var token = root.FindToken(context.Span.Start); + + var foreachStatement = GetForEachStatement(context.Span, token); + if (foreachStatement == null) + { + return; + } + + var model = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); + + var semanticFact = document.GetLanguageService(); + var options = await document.GetOptionsAsync(cancellationToken).ConfigureAwait(false); + var foreachInfo = GetForeachInfo(semanticFact, options, model, foreachStatement, cancellationToken); + if (foreachInfo == null) + { + return; + } + + if (!ValidLocation(foreachInfo)) + { + return; + } + + context.RegisterRefactoring( + new ForEachToForCodeAction( + Title, + c => ConvertForeachToForAsync(document, foreachInfo, c))); + } + + protected SyntaxToken CreateUniqueName( + ISemanticFactsService semanticFacts, SemanticModel model, SyntaxNode location, string baseName, CancellationToken cancellationToken) + => semanticFacts.GenerateUniqueLocalName(model, location, containerOpt: null, baseName, cancellationToken); + + protected SyntaxNode GetCollectionVariableName( + SemanticModel model, SyntaxGenerator generator, + ForEachInfo foreachInfo, SyntaxNode foreachCollectionExpression, CancellationToken cancellationToken) + { + if (foreachInfo.RequireCollectionStatement) + { + return generator.IdentifierName( + CreateUniqueName(foreachInfo.SemanticFacts, + model, foreachInfo.ForEachStatement, foreachInfo.CollectionNameSuggestion, cancellationToken)); + } + + return foreachCollectionExpression.WithoutTrivia().WithAdditionalAnnotations(Formatter.Annotation); + } + + protected void IntroduceCollectionStatement( + SemanticModel model, ForEachInfo foreachInfo, SyntaxEditor editor, + SyntaxNode type, SyntaxNode foreachCollectionExpression, SyntaxNode collectionVariable) + { + if (!foreachInfo.RequireCollectionStatement) + { + return; + } + + // TODO: refactor introduce variable refactoring to real service and use that service here to introduce local variable + var generator = editor.Generator; + + // attach rename annotation to control variable + var collectionVariableToken = generator.Identifier(collectionVariable.ToString()).WithAdditionalAnnotations(RenameAnnotation.Create()); + + // this expression is from user code. don't simplify this. + var expression = foreachCollectionExpression.WithoutAnnotations(SimplificationHelpers.DontSimplifyAnnotation); + var collectionStatement = generator.LocalDeclarationStatement( + type, + collectionVariableToken, + foreachInfo.RequireExplicitCastInterface + ? generator.CastExpression(foreachInfo.ExplicitCastInterface, expression) : expression); + + // attach trivia to right place + collectionStatement = collectionStatement.WithLeadingTrivia(foreachInfo.ForEachStatement.GetFirstToken().LeadingTrivia); + + editor.InsertBefore(foreachInfo.ForEachStatement, collectionStatement); + } + + protected SyntaxNode AddItemVariableDeclaration( + SyntaxGenerator generator, SyntaxNode type, SyntaxToken foreachVariable, + ITypeSymbol castType, SyntaxNode collectionVariable, SyntaxToken indexVariable) + { + var memberAccess = generator.ElementAccessExpression( + collectionVariable, generator.IdentifierName(indexVariable)); + + return generator.LocalDeclarationStatement( + type, foreachVariable, generator.CastExpression(castType, memberAccess)); + } + + private ForEachInfo GetForeachInfo( + ISemanticFactsService semanticFact, OptionSet options, SemanticModel model, + TForEachStatement foreachStatement, CancellationToken cancellationToken) + { + var operation = model.GetOperation(foreachStatement, cancellationToken) as IForEachLoopOperation; + if (operation == null || operation.Locals.Length != 1) + { + return null; + } + + var foreachVariable = operation.Locals[0]; + if (foreachVariable == null) + { + return null; + } + + // VB can have Next variable. but we only support + // simple 1 variable case. + if (operation.NextVariables.Length > 1) + { + return null; + } + + // it is okay to omit variable in Next, but if it presents, it must be same as one in the loop + if (!operation.NextVariables.IsEmpty) + { + var nextVariable = operation.NextVariables[0] as ILocalReferenceOperation; + if (nextVariable == null || nextVariable.Local?.Equals(foreachVariable) == false) + { + // we do not support anything else than local reference for next variable + // operation + return null; + } + } + + if (CheckIfForEachVariableIsWrittenInside(model, foreachVariable, foreachStatement)) + { + return null; + } + + var foreachCollection = RemoveImplicitConversion(operation.Collection); + if (foreachCollection == null) + { + return null; + } + + GetInterfaceInfo(semanticFact, model, foreachVariable, foreachCollection, + out var explicitCastInterface, out var collectionNameSuggestion, out var countName); + if (countName == null) + { + return null; + } + + var requireCollectionStatement = CheckRequireCollectionStatement(foreachCollection); + return new ForEachInfo( + semanticFact, options, collectionNameSuggestion, countName, + explicitCastInterface, foreachVariable.Type, requireCollectionStatement, foreachStatement); + } + + private static void GetInterfaceInfo( + ISemanticFactsService semanticFact, SemanticModel model, ILocalSymbol foreachVariable, IOperation foreachCollection, + out ITypeSymbol explicitCastInterface, out string collectionNameSuggestion, out string countName) + { + explicitCastInterface = default; + collectionNameSuggestion = default; + countName = default; + + // go through list of types and interfaces to find out right set; + var foreachType = foreachVariable.Type; + if (IsNullOrErrorType(foreachType)) + { + return; + } + + var collectionType = foreachCollection.Type; + if (IsNullOrErrorType(collectionType)) + { + return; + } + + // go through explicit types first. + + // check array case + if (collectionType is IArrayTypeSymbol array && array.Rank == 1) + { + if (!IsExchangable(semanticFact, array.ElementType, foreachType, model.Compilation)) + { + return; + } + + collectionNameSuggestion = "array"; + explicitCastInterface = null; + countName = Length; + return; + } + + // check string case + if (collectionType.SpecialType == SpecialType.System_String) + { + var charType = model.Compilation.GetSpecialType(SpecialType.System_Char); + if (!IsExchangable(semanticFact, charType, foreachType, model.Compilation)) + { + return; + } + + collectionNameSuggestion = "str"; + explicitCastInterface = null; + countName = Length; + return; + } + + // check ImmutableArray case + if (collectionType.OriginalDefinition.Equals(model.Compilation.GetTypeByMetadataName(typeof(ImmutableArray<>).FullName))) + { + var indexer = GetInterfaceMember(collectionType, get_Item); + if (indexer != null) + { + if (!IsExchangable(semanticFact, indexer.ReturnType, foreachType, model.Compilation)) + { + return; + } + + collectionNameSuggestion = "array"; + explicitCastInterface = null; + countName = Length; + return; + } + } + + // go through all known interfaces we support next. + var knownCollectionInterfaces = s_KnownInterfaceNames.Select( + s => model.Compilation.GetTypeByMetadataName(s)).Where(t => !IsNullOrErrorType(t)); + + // for all interfaces, we suggest collection name as "list" + collectionNameSuggestion = "list"; + + // check type itself is interface case + if (collectionType.TypeKind == TypeKind.Interface && knownCollectionInterfaces.Contains(collectionType.OriginalDefinition)) + { + var indexer = GetInterfaceMember(collectionType, get_Item); + if (indexer != null && + IsExchangable(semanticFact, indexer.ReturnType, foreachType, model.Compilation)) + { + explicitCastInterface = null; + countName = Count; + return; + } + } + + // check regular cases (implicitly implemented) + ITypeSymbol explicitInterface = null; + foreach (var current in collectionType.AllInterfaces) + { + if (!knownCollectionInterfaces.Contains(current.OriginalDefinition)) + { + continue; + } + + // see how the type implements the interface + var countSymbol = GetInterfaceMember(current, get_Count); + var indexerSymbol = GetInterfaceMember(current, get_Item); + if (countSymbol == null || indexerSymbol == null) + { + continue; + } + + var countImpl = collectionType.FindImplementationForInterfaceMember(countSymbol) as IMethodSymbol; + var indexerImpl = collectionType.FindImplementationForInterfaceMember(indexerSymbol) as IMethodSymbol; + if (countImpl == null || indexerImpl == null) + { + continue; + } + + if (!IsExchangable(semanticFact, indexerImpl.ReturnType, foreachType, model.Compilation)) + { + continue; + } + + // implicitly implemented! + if (countImpl.ExplicitInterfaceImplementations.IsEmpty && + indexerImpl.ExplicitInterfaceImplementations.IsEmpty) + { + explicitCastInterface = null; + countName = Count; + return; + } + + if (explicitInterface == null) + { + explicitInterface = current; + } + } + + // okay, we don't have implicitly implemented one, but we do have explicitly implemented one + if (explicitInterface != null) + { + explicitCastInterface = explicitInterface; + countName = Count; + } + } + + private static bool IsExchangable( + ISemanticFactsService semanticFact, ITypeSymbol type1, ITypeSymbol type2, Compilation compilation) + { + return semanticFact.IsAssignableTo(type1, type2, compilation) || + semanticFact.IsAssignableTo(type2, type1, compilation); + } + + private static bool IsNullOrErrorType(ITypeSymbol type) + => type == null || type is IErrorTypeSymbol; + + private static IMethodSymbol GetInterfaceMember(ITypeSymbol interfaceType, string memberName) + { + foreach (var current in interfaceType.GetAllInterfacesIncludingThis()) + { + var members = current.GetMembers(memberName); + if (!members.IsEmpty && members[0] is IMethodSymbol method) + { + return method; + } + } + + return null; + } + + private static bool CheckRequireCollectionStatement(IOperation operation) + { + // this lists type of references in collection part of foreach we will use + // as it is in + // var element = reference[indexer]; + // + // otherwise, we will introduce local variable for the expression first and then + // do "foreach to for" refactoring + // + // foreach(var a in new int[] {....}) + // to + // var array = new int[] { ... } + // foreach(var a in array) + switch (operation.Kind) + { + case OperationKind.LocalReference: + case OperationKind.FieldReference: + case OperationKind.ParameterReference: + case OperationKind.PropertyReference: + case OperationKind.ArrayElementReference: + return false; + default: + return true; + } + } + + private IOperation RemoveImplicitConversion(IOperation collection) + { + return (collection is IConversionOperation conversion && conversion.IsImplicit) + ? RemoveImplicitConversion(conversion.Operand) : collection; + } + + private bool CheckIfForEachVariableIsWrittenInside(SemanticModel semanticModel, ISymbol foreachVariable, TForEachStatement foreachStatement) + { + var (start, end) = GetForEachBody(foreachStatement); + if (start == null || end == null) + { + // empty body. this can happen in VB + return false; + } + + var dataFlow = semanticModel.AnalyzeDataFlow(start, end); + + if (!dataFlow.Succeeded) + { + // if we can't get good analysis, assume it is written + return true; + } + + return dataFlow.WrittenInside.Contains(foreachVariable); + } + + private async Task ConvertForeachToForAsync( + Document document, + ForEachInfo foreachInfo, + CancellationToken cancellationToken) + { + var model = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); + var workspace = document.Project.Solution.Workspace; + var editor = new SyntaxEditor(model.SyntaxTree.GetRoot(cancellationToken), workspace); + + ConvertToForStatement(model, foreachInfo, editor, cancellationToken); + + var newRoot = editor.GetChangedRoot(); + return document.WithSyntaxRoot(newRoot); + } + + protected class ForEachInfo + { + public ForEachInfo( + ISemanticFactsService semanticFacts, OptionSet options, + string collectionNameSuggestion, string countName, + ITypeSymbol explicitCastInterface, ITypeSymbol forEachElementType, + bool requireCollectionStatement, TForEachStatement forEachStatement) + { + SemanticFacts = semanticFacts; + Options = options; + + RequireExplicitCastInterface = explicitCastInterface != null; + + CollectionNameSuggestion = collectionNameSuggestion; + CountName = countName; + + ExplicitCastInterface = explicitCastInterface; + ForEachElementType = forEachElementType; + + RequireCollectionStatement = requireCollectionStatement || (explicitCastInterface != null); + + ForEachStatement = forEachStatement; + } + + public ISemanticFactsService SemanticFacts { get; } + public OptionSet Options { get; } + + public bool RequireExplicitCastInterface { get; } + public string CollectionNameSuggestion { get; } + public string CountName { get; } + public ITypeSymbol ExplicitCastInterface { get; } + public ITypeSymbol ForEachElementType { get; } + public bool RequireCollectionStatement { get; } + public TForEachStatement ForEachStatement { get; } + } + + private class ForEachToForCodeAction : CodeAction.DocumentChangeAction + { + public ForEachToForCodeAction( + string title, + Func> createChangedDocument) : base(title, createChangedDocument) + { + } + } + } +} diff --git a/src/Features/Core/Portable/ConvertForToForEach/AbstractConvertForToForEachCodeRefactoringProvider.cs b/src/Features/Core/Portable/ConvertForToForEach/AbstractConvertForToForEachCodeRefactoringProvider.cs index 75467dde10f30..3558bb6f5d0f3 100644 --- a/src/Features/Core/Portable/ConvertForToForEach/AbstractConvertForToForEachCodeRefactoringProvider.cs +++ b/src/Features/Core/Portable/ConvertForToForEach/AbstractConvertForToForEachCodeRefactoringProvider.cs @@ -349,7 +349,7 @@ private async Task ConvertForToForEachAsync( if (foreachIdentifier.RawKind == 0) { foreachIdentifier = semanticFacts.GenerateUniqueName( - semanticModel, forStatement, containerOpt: null, baseName: "v", cancellationToken); + semanticModel, forStatement, containerOpt: null, baseName: "v", usedNames: Enumerable.Empty(), cancellationToken); foreachIdentifier = foreachIdentifier.WithAdditionalAnnotations(RenameAnnotation.Create()); } diff --git a/src/Features/Core/Portable/ConvertLinq/AbstractConvertLinqQueryToForEachProvider.cs b/src/Features/Core/Portable/ConvertLinq/AbstractConvertLinqQueryToForEachProvider.cs new file mode 100644 index 0000000000000..25cc0162314b4 --- /dev/null +++ b/src/Features/Core/Portable/ConvertLinq/AbstractConvertLinqQueryToForEachProvider.cs @@ -0,0 +1,99 @@ +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.CodeAnalysis.CodeActions; +using Microsoft.CodeAnalysis.CodeRefactorings; +using Microsoft.CodeAnalysis.LanguageServices; +using Microsoft.CodeAnalysis.Shared.Extensions; +using Microsoft.CodeAnalysis.Text; + +namespace Microsoft.CodeAnalysis.ConvertLinq +{ + internal abstract class AbstractConvertLinqQueryToForEachProvider : CodeRefactoringProvider + where TQueryExpression : SyntaxNode + where TStatement : SyntaxNode + { + protected abstract string Title { get; } + + protected abstract bool TryConvert( + TQueryExpression queryExpression, + SemanticModel semanticModel, + ISemanticFactsService semanticFacts, + CancellationToken cancellationToken, + out DocumentUpdateInfo documentUpdate); + + protected abstract TQueryExpression FindNodeToRefactor(SyntaxNode root, TextSpan span); + + public override async Task ComputeRefactoringsAsync(CodeRefactoringContext context) + { + var document = context.Document; + var cancellationToken = context.CancellationToken; + var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); + + var queryExpression = FindNodeToRefactor(root, context.Span); + if (queryExpression == null) + { + return; + } + + var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); + var semanticFacts = document.GetLanguageService(); + if (TryConvert(queryExpression, semanticModel, semanticFacts, cancellationToken, out DocumentUpdateInfo documentUpdateInfo)) + { + context.RegisterRefactoring( + new MyCodeAction( + Title, + c => Task.FromResult(document.WithSyntaxRoot(documentUpdateInfo.UpdateRoot(root))))); + } + } + + /// + /// Handles information about updating the document with the refactoring. + /// + internal sealed class DocumentUpdateInfo + { + public readonly TStatement Source; + public readonly ImmutableArray Destinations; + + public DocumentUpdateInfo(TStatement source, TStatement destination) : this(source, new[] { destination }) + { + } + + public DocumentUpdateInfo(TStatement source, IEnumerable destinations) + { + Source = source; + Destinations = ImmutableArray.CreateRange(destinations); + } + + /// + /// Updates the root of the docuemtn with the document update. + /// + public SyntaxNode UpdateRoot(SyntaxNode root) + { + // There are two overloads of ReplaceNode: one accepts a collection of nodes and another a single node. + // If we replace a node, e.g. in statement of an if-statement(without block), + // it cannot replace it with collection even if there is a just 1 element in it. + if (Destinations.Length == 1) + { + return root.ReplaceNode(Source, Destinations[0]); + } + else + { + return root.ReplaceNode(Source, Destinations); + } + } + } + + protected sealed class MyCodeAction : CodeAction.DocumentChangeAction + { + public MyCodeAction(string title, Func> createChangedDocument) + : base(title, createChangedDocument) + { + } + } + } +} diff --git a/src/Features/Core/Portable/IntroduceVariable/AbstractIntroduceVariableService.cs b/src/Features/Core/Portable/IntroduceVariable/AbstractIntroduceVariableService.cs index af8c40928e003..55c1b79ece44e 100644 --- a/src/Features/Core/Portable/IntroduceVariable/AbstractIntroduceVariableService.cs +++ b/src/Features/Core/Portable/IntroduceVariable/AbstractIntroduceVariableService.cs @@ -227,7 +227,7 @@ protected static SyntaxToken GenerateUniqueLocalName( var baseName = semanticFacts.GenerateNameForExpression( semanticModel, expression, capitalize: isConstant, cancellationToken: cancellationToken); - return semanticFacts.GenerateUniqueName( + return semanticFacts.GenerateUniqueLocalName( semanticModel, expression, containerOpt, baseName, cancellationToken); } diff --git a/src/Features/VisualBasic/Portable/ConvertForEachToFor/VisualBasicConvertForEachToForCodeRefactoringProvider.vb b/src/Features/VisualBasic/Portable/ConvertForEachToFor/VisualBasicConvertForEachToForCodeRefactoringProvider.vb new file mode 100644 index 0000000000000..26c4976b60c3e --- /dev/null +++ b/src/Features/VisualBasic/Portable/ConvertForEachToFor/VisualBasicConvertForEachToForCodeRefactoringProvider.vb @@ -0,0 +1,181 @@ +' 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 System.Composition +Imports System.Threading +Imports Microsoft.CodeAnalysis.CodeActions +Imports Microsoft.CodeAnalysis.CodeRefactorings +Imports Microsoft.CodeAnalysis.Editing +Imports Microsoft.CodeAnalysis.ConvertForEachToFor +Imports Microsoft.CodeAnalysis.Text +Imports Microsoft.CodeAnalysis.VisualBasic.Syntax + +Namespace Microsoft.CodeAnalysis.VisualBasic.ConvertForEachToFor + + Friend Class VisualBasicConvertForEachToForCodeRefactoringProvider + Inherits AbstractConvertForEachToForCodeRefactoringProvider(Of ForEachBlockSyntax) + + Protected Overrides ReadOnly Property Title As String = VBFeaturesResources.Convert_to_For + + Protected Overrides Function GetForEachStatement(selection As TextSpan, token As SyntaxToken) As ForEachBlockSyntax + Dim forEachBlock = token.Parent.FirstAncestorOrSelf(Of ForEachBlockSyntax)() + If forEachBlock Is Nothing Then + Return Nothing + End If + + ' support refactoring only if caret Is on for each statement + Dim scope = forEachBlock.ForEachStatement.Span + If Not scope.IntersectsWith(selection) Then + Return Nothing + End If + + ' we don't support colon seperated statements + If forEachBlock.DescendantTrivia().Any(Function(t) t.IsKind(SyntaxKind.ColonTrivia)) Then + Return Nothing + End If + + ' check whether there Is any comments or line continuation within foreach statement + ' if they do, we don't support conversion. + For Each trivia In forEachBlock.ForEachStatement.DescendantTrivia() + If trivia.Span.End <= scope.Start OrElse + scope.End <= trivia.Span.Start Then + Continue For + End If + + If trivia.Kind() <> SyntaxKind.WhitespaceTrivia AndAlso + trivia.Kind() <> SyntaxKind.EndOfLineTrivia AndAlso + trivia.Kind() <> SyntaxKind.LineContinuationTrivia Then + ' we don't know what to do with these + Return Nothing + End If + Next + + Return forEachBlock + End Function + + Protected Overrides Function ValidLocation(foreachInfo As ForEachInfo) As Boolean + ' all places where for each can appear is valid location for vb + Return True + End Function + + Protected Overrides Function GetForEachBody(foreachBlock As ForEachBlockSyntax) As (start As SyntaxNode, [end] As SyntaxNode) + If foreachBlock.Statements.Count = 0 Then + Return Nothing + End If + + Return (foreachBlock.Statements(0), foreachBlock.Statements(foreachBlock.Statements.Count - 1)) + End Function + + Protected Overrides Sub ConvertToForStatement(model As SemanticModel, foreachInfo As ForEachInfo, editor As SyntaxEditor, cancellationToken As CancellationToken) + cancellationToken.ThrowIfCancellationRequested() + + Dim generator = editor.Generator + Dim forEachBlock = foreachInfo.ForEachStatement + + ' trailing triva of expression will be attached to for statement below + Dim foreachCollectionExpression = forEachBlock.ForEachStatement.Expression + Dim collectionVariable = GetCollectionVariableName( + model, generator, foreachInfo, foreachCollectionExpression, cancellationToken) + + ' make sure we get rid of all comments from expression since that will be re-attached to for statement + Dim expression = foreachCollectionExpression.WithTrailingTrivia( + foreachCollectionExpression.GetTrailingTrivia().Where(Function(t) t.IsWhitespaceOrEndOfLine())) + + ' and remove all trailing trivia if it is used for cast + If foreachInfo.RequireExplicitCastInterface Then + expression = expression.WithoutTrailingTrivia() + End If + + ' first, see whether we need to introduce New statement to capture collection + IntroduceCollectionStatement(model, foreachInfo, editor, type:=Nothing, expression, collectionVariable) + + ' create New index varialbe name + Dim indexVariable = If( + forEachBlock.Statements.Count = 0, + generator.Identifier("i"), + CreateUniqueName(foreachInfo.SemanticFacts, model, forEachBlock.Statements(0), "i", cancellationToken)) + + ' put variable statement in body + Dim bodyStatement = GetForLoopBody(generator, foreachInfo, collectionVariable, indexVariable) + + Dim nextStatement = forEachBlock.NextStatement + + If nextStatement.ControlVariables.Count > 0 Then + Contract.Requires(nextStatement.ControlVariables.Count = 1) + + Dim controlVariable As SyntaxNode = nextStatement.ControlVariables(0) + controlVariable = generator.IdentifierName( + indexVariable _ + .WithLeadingTrivia(controlVariable.GetFirstToken().LeadingTrivia) _ + .WithTrailingTrivia(controlVariable.GetLastToken().TrailingTrivia)) + + nextStatement = nextStatement.WithControlVariables( + SyntaxFactory.SingletonSeparatedList(controlVariable)) + End If + + ' create for statement from foreach statement + Dim forBlock = SyntaxFactory.ForBlock( + SyntaxFactory.ForStatement( + DirectCast(generator.IdentifierName(indexVariable.WithAdditionalAnnotations(RenameAnnotation.Create())), VisualBasicSyntaxNode), + DirectCast(generator.LiteralExpression(0), ExpressionSyntax), + DirectCast(generator.SubtractExpression( + generator.MemberAccessExpression( + collectionVariable, foreachInfo.CountName), generator.LiteralExpression(1)), ExpressionSyntax)), + bodyStatement, + nextStatement) + + If foreachInfo.RequireCollectionStatement Then + ' this is to remove blank line between newly added collection statement with "For" keyword. + ' default VB formatting rule around elastic trivia and end of line trivia is converting elastic trivia + ' to end of line trivia causing there to be 2 line breaks. this fix that issue. not changing the default + ' rule since it will affect other ones that having opposite desire. + forBlock = forBlock.WithLeadingTrivia(SyntaxFactory.TriviaList()) + Else + ' transfer comment on "For Each" to "For" + forBlock = forBlock.WithLeadingTrivia(forEachBlock.GetLeadingTrivia()) + End If + + ' transfer comment at then end of "For Each" to "For" + forBlock = forBlock.WithForStatement(forBlock.ForStatement.WithTrailingTrivia(forEachBlock.ForEachStatement.GetLastToken().TrailingTrivia)) + + editor.ReplaceNode(forEachBlock, forBlock) + End Sub + + Private Function GetForLoopBody( + generator As SyntaxGenerator, foreachInfo As ForEachInfo, + collectionVariableName As SyntaxNode, indexVariable As SyntaxToken) As SyntaxList(Of StatementSyntax) + + Dim forEachBlock = foreachInfo.ForEachStatement + If forEachBlock.Statements.Count = 0 Then + Return forEachBlock.Statements + End If + + Dim foreachVariable As SyntaxNode = Nothing + Dim type As SyntaxNode = Nothing + GetVariableNameAndType(forEachBlock.ForEachStatement, foreachVariable, type) + + ' use original text + Dim foreachVariableToken = generator.Identifier(foreachVariable.ToString()) + + ' create varialbe statement + Dim variableStatement = AddItemVariableDeclaration( + generator, type, foreachVariableToken, foreachInfo.ForEachElementType, collectionVariableName, indexVariable) + + Return forEachBlock.Statements.Insert(0, DirectCast(variableStatement, StatementSyntax)) + End Function + + Private Sub GetVariableNameAndType( + forEachStatement As ForEachStatementSyntax, ByRef foreachVariable As SyntaxNode, ByRef type As SyntaxNode) + + Dim controlVariable = forEachStatement.ControlVariable + + Dim declarator = TryCast(controlVariable, VariableDeclaratorSyntax) + If declarator IsNot Nothing Then + foreachVariable = declarator.Names(0) + type = declarator.AsClause.Type + Else + foreachVariable = controlVariable + type = Nothing + End If + End Sub + End Class +End Namespace diff --git a/src/Features/VisualBasic/Portable/ConvertForToForEach/VisualBasicConvertForToForEachCodeRefactoringProvider.vb b/src/Features/VisualBasic/Portable/ConvertForToForEach/VisualBasicConvertForToForEachCodeRefactoringProvider.vb index 3e7d5542c76c7..94e90d926c849 100644 --- a/src/Features/VisualBasic/Portable/ConvertForToForEach/VisualBasicConvertForToForEachCodeRefactoringProvider.vb +++ b/src/Features/VisualBasic/Portable/ConvertForToForEach/VisualBasicConvertForToForEachCodeRefactoringProvider.vb @@ -20,7 +20,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ConvertForToForEach VariableDeclaratorSyntax) Protected Overrides Function GetTitle() As String - Return VBFeaturesResources.Convert_For_to_For_Each + Return VBFeaturesResources.Convert_to_For_Each End Function Protected Overrides Function IsValidCursorPosition(forBlock As ForBlockSyntax, cursorPos As Integer) As Boolean diff --git a/src/Features/VisualBasic/Portable/ConvertIfToSwitch/VisualBasicConvertIfToSwitchCodeRefactoringProvider.vb b/src/Features/VisualBasic/Portable/ConvertIfToSwitch/VisualBasicConvertIfToSwitchCodeRefactoringProvider.vb index 59cd98e92ad31..7d7c69bb1ea91 100644 --- a/src/Features/VisualBasic/Portable/ConvertIfToSwitch/VisualBasicConvertIfToSwitchCodeRefactoringProvider.vb +++ b/src/Features/VisualBasic/Portable/ConvertIfToSwitch/VisualBasicConvertIfToSwitchCodeRefactoringProvider.vb @@ -26,7 +26,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ConvertIfToSwitch Protected Overrides ReadOnly Property Title As String Get - Return VBFeaturesResources.Convert_If_to_Select_Case + Return VBFeaturesResources.Convert_to_Select_Case End Get End Property diff --git a/src/Features/VisualBasic/Portable/VBFeaturesResources.Designer.vb b/src/Features/VisualBasic/Portable/VBFeaturesResources.Designer.vb index 90b7c2b69a3a6..d3fca22a29cd9 100644 --- a/src/Features/VisualBasic/Portable/VBFeaturesResources.Designer.vb +++ b/src/Features/VisualBasic/Portable/VBFeaturesResources.Designer.vb @@ -477,20 +477,29 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.VBFeaturesResources End Property ''' - ''' Looks up a localized string similar to Convert 'For' to 'For Each'. + ''' Looks up a localized string similar to Convert to 'For'. ''' - Friend ReadOnly Property Convert_For_to_For_Each() As String + Friend ReadOnly Property Convert_to_For() As String Get - Return ResourceManager.GetString("Convert_For_to_For_Each", resourceCulture) + Return ResourceManager.GetString("Convert_to_For", resourceCulture) End Get End Property ''' - ''' Looks up a localized string similar to Convert 'If' to 'Select Case'. + ''' Looks up a localized string similar to Convert to 'For Each'. ''' - Friend ReadOnly Property Convert_If_to_Select_Case() As String + Friend ReadOnly Property Convert_to_For_Each() As String Get - Return ResourceManager.GetString("Convert_If_to_Select_Case", resourceCulture) + Return ResourceManager.GetString("Convert_to_For_Each", resourceCulture) + End Get + End Property + + ''' + ''' Looks up a localized string similar to Convert to 'Select Case'. + ''' + Friend ReadOnly Property Convert_to_Select_Case() As String + Get + Return ResourceManager.GetString("Convert_to_Select_Case", resourceCulture) End Get End Property diff --git a/src/Features/VisualBasic/Portable/VBFeaturesResources.resx b/src/Features/VisualBasic/Portable/VBFeaturesResources.resx index 93ebeba879db7..73ef1bf0e7092 100644 --- a/src/Features/VisualBasic/Portable/VBFeaturesResources.resx +++ b/src/Features/VisualBasic/Portable/VBFeaturesResources.resx @@ -1238,8 +1238,8 @@ Sub(<parameterList>) <statement> Add 'Me.' - - Convert 'If' to 'Select Case' + + Convert to 'Select Case' Use 'Is Nothing' check @@ -1247,7 +1247,10 @@ Sub(<parameterList>) <statement> Use 'IsNot Nothing' check - - Convert 'For' to 'For Each' + + Convert to 'For Each' + + + Convert to 'For' \ No newline at end of file diff --git a/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.cs.xlf b/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.cs.xlf index 2d0a0bbcc8e08..e0dbe7ad1723f 100644 --- a/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.cs.xlf +++ b/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.cs.xlf @@ -1802,11 +1802,6 @@ Sub(<seznam_parametrů>) <výraz> Přidejte položku Me. - - Convert 'If' to 'Select Case' - Převést If na Select Case - - Use 'Is Nothing' check Použít kontrolu „Is Nothing“ @@ -1817,9 +1812,19 @@ Sub(<seznam_parametrů>) <výraz> Použít kontrolu „IsNot Nothing“ - - Convert 'For' to 'For Each' - Convert 'For' to 'For Each' + + Convert to 'Select Case' + Convert to 'Select Case' + + + + Convert to 'For Each' + Convert to 'For Each' + + + + Convert to 'For' + Convert to 'For' diff --git a/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.de.xlf b/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.de.xlf index 977dd3c1c9380..92b344108b09c 100644 --- a/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.de.xlf +++ b/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.de.xlf @@ -1802,11 +1802,6 @@ Sub(<Parameterliste>) <Ausdruck> "Me." hinzufügen - - Convert 'If' to 'Select Case' - "If" in "Select Case" konvertieren - - Use 'Is Nothing' check Prüfung "Is Nothing" verwenden @@ -1817,9 +1812,19 @@ Sub(<Parameterliste>) <Ausdruck> Prüfung "IsNot Nothing" verwenden - - Convert 'For' to 'For Each' - Convert 'For' to 'For Each' + + Convert to 'Select Case' + Convert to 'Select Case' + + + + Convert to 'For Each' + Convert to 'For Each' + + + + Convert to 'For' + Convert to 'For' diff --git a/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.es.xlf b/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.es.xlf index fe31b68edc6ee..dfe5663a817a6 100644 --- a/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.es.xlf +++ b/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.es.xlf @@ -1802,11 +1802,6 @@ Sub(<listaDeParámetros>) <instrucción> Agregar "Me." - - Convert 'If' to 'Select Case' - Convertir "If" en "Select Case" - - Use 'Is Nothing' check Usar comprobación "Is Nothing" @@ -1817,9 +1812,19 @@ Sub(<listaDeParámetros>) <instrucción> Usar comprobación "IsNot Nothing" - - Convert 'For' to 'For Each' - Convert 'For' to 'For Each' + + Convert to 'Select Case' + Convert to 'Select Case' + + + + Convert to 'For Each' + Convert to 'For Each' + + + + Convert to 'For' + Convert to 'For' diff --git a/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.fr.xlf b/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.fr.xlf index 75c16a482d093..58be65b9d111c 100644 --- a/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.fr.xlf +++ b/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.fr.xlf @@ -1802,11 +1802,6 @@ Sub(<parameterList>) <statement> Ajouter 'Me.' - - Convert 'If' to 'Select Case' - Convertir 'If' en 'Select Case' - - Use 'Is Nothing' check Utiliser la vérification 'Is Nothing' @@ -1817,9 +1812,19 @@ Sub(<parameterList>) <statement> Utiliser la vérification 'IsNot Nothing' - - Convert 'For' to 'For Each' - Convert 'For' to 'For Each' + + Convert to 'Select Case' + Convert to 'Select Case' + + + + Convert to 'For Each' + Convert to 'For Each' + + + + Convert to 'For' + Convert to 'For' diff --git a/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.it.xlf b/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.it.xlf index b3a8880ac44d9..9c7cf80e29821 100644 --- a/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.it.xlf +++ b/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.it.xlf @@ -1802,11 +1802,6 @@ Sub(<elencoParametri>) <istruzione> Aggiungi 'Me.' - - Convert 'If' to 'Select Case' - Converti 'If' in 'Select Case' - - Use 'Is Nothing' check Usa controllo 'Is Nothing' @@ -1817,9 +1812,19 @@ Sub(<elencoParametri>) <istruzione> Usa controllo 'IsNot Nothing' - - Convert 'For' to 'For Each' - Convert 'For' to 'For Each' + + Convert to 'Select Case' + Convert to 'Select Case' + + + + Convert to 'For Each' + Convert to 'For Each' + + + + Convert to 'For' + Convert to 'For' diff --git a/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.ja.xlf b/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.ja.xlf index 71961d88592fa..8dd9d5eaa0104 100644 --- a/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.ja.xlf +++ b/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.ja.xlf @@ -1801,11 +1801,6 @@ Sub(<parameterList>) <statement> Me' を追加します。 - - Convert 'If' to 'Select Case' - If' を 'Select Case' に変換する - - Use 'Is Nothing' check Is Nothing' チェックを使用します @@ -1816,9 +1811,19 @@ Sub(<parameterList>) <statement> IsNot Nothing' チェックを使用します - - Convert 'For' to 'For Each' - Convert 'For' to 'For Each' + + Convert to 'Select Case' + Convert to 'Select Case' + + + + Convert to 'For Each' + Convert to 'For Each' + + + + Convert to 'For' + Convert to 'For' diff --git a/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.ko.xlf b/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.ko.xlf index 3eaecc3423540..6f8a382862f06 100644 --- a/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.ko.xlf +++ b/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.ko.xlf @@ -1802,11 +1802,6 @@ Sub(<parameterList>) <statement> Me'를 추가하세요. - - Convert 'If' to 'Select Case' - If'를 'Select Case'로 변환 - - Use 'Is Nothing' check Is Nothing' 검사 사용 @@ -1817,9 +1812,19 @@ Sub(<parameterList>) <statement> IsNot Nothing' 검사 사용 - - Convert 'For' to 'For Each' - Convert 'For' to 'For Each' + + Convert to 'Select Case' + Convert to 'Select Case' + + + + Convert to 'For Each' + Convert to 'For Each' + + + + Convert to 'For' + Convert to 'For' diff --git a/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.pl.xlf b/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.pl.xlf index 0b496621ea410..8e0ac037420f0 100644 --- a/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.pl.xlf +++ b/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.pl.xlf @@ -1802,11 +1802,6 @@ Sub(<listaParametrów>) <instrukcja> Dodaj „mnie”. - - Convert 'If' to 'Select Case' - Konwertuj wyrażenie „If” na „Select Case” - - Use 'Is Nothing' check Użyj sprawdzania „Is Nothing” @@ -1817,9 +1812,19 @@ Sub(<listaParametrów>) <instrukcja> Użyj sprawdzania „IsNot Nothing” - - Convert 'For' to 'For Each' - Convert 'For' to 'For Each' + + Convert to 'Select Case' + Convert to 'Select Case' + + + + Convert to 'For Each' + Convert to 'For Each' + + + + Convert to 'For' + Convert to 'For' diff --git a/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.pt-BR.xlf b/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.pt-BR.xlf index 18af243c52457..0880f129090a6 100644 --- a/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.pt-BR.xlf +++ b/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.pt-BR.xlf @@ -1802,11 +1802,6 @@ Sub(<parameterList>) <statement> Adicionar 'Me.' - - Convert 'If' to 'Select Case' - Converter 'If' em 'Select Case' - - Use 'Is Nothing' check Usar a verificação 'Is Nothing' @@ -1817,9 +1812,19 @@ Sub(<parameterList>) <statement> Usar a verificação 'IsNot Nothing' - - Convert 'For' to 'For Each' - Convert 'For' to 'For Each' + + Convert to 'Select Case' + Convert to 'Select Case' + + + + Convert to 'For Each' + Convert to 'For Each' + + + + Convert to 'For' + Convert to 'For' diff --git a/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.ru.xlf b/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.ru.xlf index 33ed26a593981..bb1f6ace4df87 100644 --- a/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.ru.xlf +++ b/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.ru.xlf @@ -1802,11 +1802,6 @@ Sub(<parameterList>) <statement> Добавьте "'Me". - - Convert 'If' to 'Select Case' - Преобразовать If в Select Case - - Use 'Is Nothing' check Использовать флажок "Is Nothing" @@ -1817,9 +1812,19 @@ Sub(<parameterList>) <statement> Использовать флажок "IsNot Nothing" - - Convert 'For' to 'For Each' - Convert 'For' to 'For Each' + + Convert to 'Select Case' + Convert to 'Select Case' + + + + Convert to 'For Each' + Convert to 'For Each' + + + + Convert to 'For' + Convert to 'For' diff --git a/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.tr.xlf b/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.tr.xlf index 4b5ec669c4c14..161958c5c1b68 100644 --- a/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.tr.xlf +++ b/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.tr.xlf @@ -1802,11 +1802,6 @@ Sub(<parameterList>) <statement> Me' ekleyin. - - Convert 'If' to 'Select Case' - If' deyimini 'Select Case' deyimine dönüştür - - Use 'Is Nothing' check Is Nothing' denetimi kullan @@ -1817,9 +1812,19 @@ Sub(<parameterList>) <statement> IsNot Nothing' denetimi kullan - - Convert 'For' to 'For Each' - Convert 'For' to 'For Each' + + Convert to 'Select Case' + Convert to 'Select Case' + + + + Convert to 'For Each' + Convert to 'For Each' + + + + Convert to 'For' + Convert to 'For' diff --git a/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.zh-Hans.xlf b/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.zh-Hans.xlf index 092dfffb0b953..f98fb4e21bdfc 100644 --- a/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.zh-Hans.xlf +++ b/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.zh-Hans.xlf @@ -1802,11 +1802,6 @@ Sub(<parameterList>) <statement> 添加 "Me." - - Convert 'If' to 'Select Case' - 将 "If" 转换为 "Select Case" - - Use 'Is Nothing' check 使用 "Is Nothing" 检查 @@ -1817,9 +1812,19 @@ Sub(<parameterList>) <statement> 使用 "IsNot Nothing" 检查 - - Convert 'For' to 'For Each' - Convert 'For' to 'For Each' + + Convert to 'Select Case' + Convert to 'Select Case' + + + + Convert to 'For Each' + Convert to 'For Each' + + + + Convert to 'For' + Convert to 'For' diff --git a/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.zh-Hant.xlf b/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.zh-Hant.xlf index 442cc04268a3a..e219785543500 100644 --- a/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.zh-Hant.xlf +++ b/src/Features/VisualBasic/Portable/xlf/VBFeaturesResources.zh-Hant.xlf @@ -1802,11 +1802,6 @@ Sub(<parameterList>) <statement> 新增 'Me.' - - Convert 'If' to 'Select Case' - 將 'If' 轉換為 'Select Case' - - Use 'Is Nothing' check 使用 'Is Nothing' 檢查 @@ -1817,9 +1812,19 @@ Sub(<parameterList>) <statement> 使用 'IsNot Nothing' 檢查 - - Convert 'For' to 'For Each' - Convert 'For' to 'For Each' + + Convert to 'Select Case' + Convert to 'Select Case' + + + + Convert to 'For Each' + Convert to 'For Each' + + + + Convert to 'For' + Convert to 'For' diff --git a/src/Interactive/EditorFeatures/CSharp/CSharpInteractiveEditorFeatures.csproj b/src/Interactive/EditorFeatures/CSharp/CSharpInteractiveEditorFeatures.csproj index babb32a923abd..0db2721857295 100644 --- a/src/Interactive/EditorFeatures/CSharp/CSharpInteractiveEditorFeatures.csproj +++ b/src/Interactive/EditorFeatures/CSharp/CSharpInteractiveEditorFeatures.csproj @@ -7,7 +7,7 @@ Library Microsoft.CodeAnalysis.Editor.CSharp Microsoft.CodeAnalysis.CSharp.InteractiveEditorFeatures - net461 + net46 diff --git a/src/Interactive/EditorFeatures/VisualBasic/BasicInteractiveEditorFeatures.vbproj b/src/Interactive/EditorFeatures/VisualBasic/BasicInteractiveEditorFeatures.vbproj index 1317d8fd682c2..355debaee9768 100644 --- a/src/Interactive/EditorFeatures/VisualBasic/BasicInteractiveEditorFeatures.vbproj +++ b/src/Interactive/EditorFeatures/VisualBasic/BasicInteractiveEditorFeatures.vbproj @@ -6,7 +6,7 @@ AnyCPU Library Microsoft.CodeAnalysis.VisualBasic.InteractiveEditorFeatures - net461 + net46 diff --git a/src/Interactive/Host/InteractiveHost.csproj b/src/Interactive/Host/InteractiveHost.csproj index 25eed4d9fd6d6..ca03f0a12d2ac 100644 --- a/src/Interactive/Host/InteractiveHost.csproj +++ b/src/Interactive/Host/InteractiveHost.csproj @@ -6,7 +6,7 @@ AnyCPU AnyCPU Exe - net461 + net46 $(RoslynDesktopRuntimeIdentifier) diff --git a/src/Interactive/HostTest/InteractiveHostTest.csproj b/src/Interactive/HostTest/InteractiveHostTest.csproj index d0cecd114fcbd..3e14800d63a12 100644 --- a/src/Interactive/HostTest/InteractiveHostTest.csproj +++ b/src/Interactive/HostTest/InteractiveHostTest.csproj @@ -8,7 +8,7 @@ Library Roslyn.InteractiveHost.UnitTests Roslyn.InteractiveHost.UnitTests - net461 + net46 $(RoslynDesktopRuntimeIdentifierX86) UnitTest diff --git a/src/Interactive/csi/csi.csproj b/src/Interactive/csi/csi.csproj index 871fed515e3ef..57e05e5fe52dc 100644 --- a/src/Interactive/csi/csi.csproj +++ b/src/Interactive/csi/csi.csproj @@ -7,7 +7,7 @@ AnyCPU Exe CSharpInteractive - $(RoslynPortableTargetFrameworks46) + $(RoslynPortableTargetFrameworks) $(RoslynPortableRuntimeIdentifiers) diff --git a/src/Interactive/vbi/vbi.vbproj b/src/Interactive/vbi/vbi.vbproj index 33ede4695f112..4b404da2e3130 100644 --- a/src/Interactive/vbi/vbi.vbproj +++ b/src/Interactive/vbi/vbi.vbproj @@ -7,7 +7,7 @@ AnyCPU Exe Sub Main - $(RoslynPortableTargetFrameworks46) + $(RoslynPortableTargetFrameworks) $(RoslynPortableRuntimeIdentifiers) diff --git a/src/NuGet/Microsoft.VisualStudio.IntegrationTest.Utilities.nuspec b/src/NuGet/Microsoft.VisualStudio.IntegrationTest.Utilities.nuspec index eaf7c329429c1..39a007d47c7a2 100644 --- a/src/NuGet/Microsoft.VisualStudio.IntegrationTest.Utilities.nuspec +++ b/src/NuGet/Microsoft.VisualStudio.IntegrationTest.Utilities.nuspec @@ -27,8 +27,8 @@ - - - + + + diff --git a/src/Scripting/CoreTest.Desktop/ScriptingTest.Desktop.csproj b/src/Scripting/CoreTest.Desktop/ScriptingTest.Desktop.csproj index 4cbdc07200208..1a08b2ecccbc4 100644 --- a/src/Scripting/CoreTest.Desktop/ScriptingTest.Desktop.csproj +++ b/src/Scripting/CoreTest.Desktop/ScriptingTest.Desktop.csproj @@ -9,7 +9,7 @@ Microsoft.CodeAnalysis.Scripting.Test Microsoft.CodeAnalysis.Scripting.Desktop.UnitTests true - net461 + net46 $(RoslynDesktopRuntimeIdentifier) UnitTest diff --git a/src/Scripting/VisualBasicTest.Desktop/BasicScriptingTest.Desktop.vbproj b/src/Scripting/VisualBasicTest.Desktop/BasicScriptingTest.Desktop.vbproj index e596eacdf2ff6..03b16c162864a 100644 --- a/src/Scripting/VisualBasicTest.Desktop/BasicScriptingTest.Desktop.vbproj +++ b/src/Scripting/VisualBasicTest.Desktop/BasicScriptingTest.Desktop.vbproj @@ -9,7 +9,7 @@ Properties Microsoft.CodeAnalysis.VisualBasic.Scripting.Desktop.UnitTests true - net461 + net46 $(RoslynDesktopRuntimeIdentifier) UnitTest diff --git a/src/Scripting/VisualBasicTest/BasicScriptingTest.vbproj b/src/Scripting/VisualBasicTest/BasicScriptingTest.vbproj index ee9b002369ae8..f77c522343b27 100644 --- a/src/Scripting/VisualBasicTest/BasicScriptingTest.vbproj +++ b/src/Scripting/VisualBasicTest/BasicScriptingTest.vbproj @@ -7,7 +7,7 @@ AnyCPU Library Microsoft.CodeAnalysis.VisualBasic.Scripting.UnitTests - net461 + net46 UnitTest diff --git a/src/Setup/DevDivInsertionFiles/BuildDevDivInsertionFiles.vb b/src/Setup/DevDivInsertionFiles/BuildDevDivInsertionFiles.vb index 0a1abb9c433b2..01e66e90e45da 100644 --- a/src/Setup/DevDivInsertionFiles/BuildDevDivInsertionFiles.vb +++ b/src/Setup/DevDivInsertionFiles/BuildDevDivInsertionFiles.vb @@ -560,7 +560,10 @@ Public Class BuildDevDivInsertionFiles packageName, packageVersion, isNative:=native IsNot Nothing, - isFacade:=frameworkAssemblies IsNot Nothing AndAlso packageName <> "Microsoft.Build" OrElse packageName = "System.IO.Pipes.AccessControl")) + isFacade:=(frameworkAssemblies IsNot Nothing AndAlso + packageName <> "Microsoft.Build" AndAlso + packageName <> "Microsoft.DiaSymReader") OrElse + packageName = "System.IO.Pipes.AccessControl")) End If Next Next @@ -845,12 +848,12 @@ Public Class BuildDevDivInsertionFiles add("UnitTests\EditorServicesTest\BasicUndo.dll") add("UnitTests\EditorServicesTest\Moq.dll") add("UnitTests\EditorServicesTest\Microsoft.CodeAnalysis.Test.Resources.Proprietary.dll") - add("UnitTests\CSharpCompilerEmitTest\net461\Microsoft.DiaSymReader.PortablePdb.dll") - add("UnitTests\CSharpCompilerEmitTest\net461\Microsoft.DiaSymReader.Converter.dll") - add("UnitTests\CSharpCompilerEmitTest\net461\Microsoft.DiaSymReader.Converter.Xml.dll") - add("UnitTests\CSharpCompilerEmitTest\net461\Microsoft.DiaSymReader.dll") - add("UnitTests\CSharpCompilerEmitTest\net461\Microsoft.DiaSymReader.Native.amd64.dll") - add("UnitTests\CSharpCompilerEmitTest\net461\Microsoft.DiaSymReader.Native.x86.dll") + add("UnitTests\CSharpCompilerEmitTest\net46\Microsoft.DiaSymReader.PortablePdb.dll") + add("UnitTests\CSharpCompilerEmitTest\net46\Microsoft.DiaSymReader.Converter.dll") + add("UnitTests\CSharpCompilerEmitTest\net46\Microsoft.DiaSymReader.Converter.Xml.dll") + add("UnitTests\CSharpCompilerEmitTest\net46\Microsoft.DiaSymReader.dll") + add("UnitTests\CSharpCompilerEmitTest\net46\Microsoft.DiaSymReader.Native.amd64.dll") + add("UnitTests\CSharpCompilerEmitTest\net46\Microsoft.DiaSymReader.Native.x86.dll") add("Vsix\ExpressionEvaluatorPackage\Microsoft.VisualStudio.Debugger.Engine.dll") add("Vsix\VisualStudioIntegrationTestSetup\Microsoft.Diagnostics.Runtime.dll") add("Exes\Toolset\System.AppContext.dll") diff --git a/src/Setup/DevDivVsix/CompilersPackage/Microsoft.CodeAnalysis.Compilers.vsmanproj b/src/Setup/DevDivVsix/CompilersPackage/Microsoft.CodeAnalysis.Compilers.vsmanproj index 560b2cfa7c8b5..b136223547465 100644 --- a/src/Setup/DevDivVsix/CompilersPackage/Microsoft.CodeAnalysis.Compilers.vsmanproj +++ b/src/Setup/DevDivVsix/CompilersPackage/Microsoft.CodeAnalysis.Compilers.vsmanproj @@ -22,10 +22,6 @@ - - - - diff --git a/src/Setup/DevDivVsix/PortableFacades/PortableFacades.vsmanproj b/src/Setup/DevDivVsix/PortableFacades/PortableFacades.vsmanproj index 5e577625e1766..5e2d40d55fa65 100644 --- a/src/Setup/DevDivVsix/PortableFacades/PortableFacades.vsmanproj +++ b/src/Setup/DevDivVsix/PortableFacades/PortableFacades.vsmanproj @@ -22,10 +22,6 @@ - - - - diff --git a/src/Test/Diagnostics/Diagnostics.csproj b/src/Test/Diagnostics/Diagnostics.csproj index a19e77f3118e7..894091b32cd8c 100644 --- a/src/Test/Diagnostics/Diagnostics.csproj +++ b/src/Test/Diagnostics/Diagnostics.csproj @@ -7,7 +7,7 @@ Library Roslyn.Hosting.Diagnostics Roslyn.Hosting.Diagnostics - net461 + net46 diff --git a/src/Test/PdbUtilities/Reader/PdbValidation.cs b/src/Test/PdbUtilities/Reader/PdbValidation.cs index f9712c4c6bbc1..a088d6c112d06 100644 --- a/src/Test/PdbUtilities/Reader/PdbValidation.cs +++ b/src/Test/PdbUtilities/Reader/PdbValidation.cs @@ -20,7 +20,6 @@ using Microsoft.DiaSymReader; using Microsoft.DiaSymReader.Tools; using Microsoft.Metadata.Tools; -using Roslyn.Reflection.PortableExecutable; using Roslyn.Test.PdbUtilities; using Roslyn.Test.Utilities; using Roslyn.Utilities; diff --git a/src/Test/Utilities/Portable/Assert/UseCultureAttribute.cs b/src/Test/Utilities/Portable/Assert/UseCultureAttribute.cs index cb485d7ea1538..7ee43bdde3179 100644 --- a/src/Test/Utilities/Portable/Assert/UseCultureAttribute.cs +++ b/src/Test/Utilities/Portable/Assert/UseCultureAttribute.cs @@ -51,7 +51,7 @@ public UseCultureAttribute(string culture) /// The name of the UI culture. public UseCultureAttribute(string culture, string uiCulture) { -#if NET46 || NET461 +#if NET46 _culture = new Lazy(() => new CultureInfo(culture, useUserOverride: false)); _uiCulture = new Lazy(() => new CultureInfo(uiCulture, useUserOverride: false)); #elif NETCOREAPP2_0 @@ -83,11 +83,11 @@ public override void Before(MethodInfo methodUnderTest) _originalCulture = CultureInfo.CurrentCulture; _originalUICulture = CultureInfo.CurrentUICulture; -#if NET46 || NET461 || NETCOREAPP2_0 +#if NET46 || NETCOREAPP2_0 CultureInfo.CurrentCulture = Culture; CultureInfo.CurrentUICulture = UICulture; -#if NET46 || NET461 +#if NET46 CultureInfo.CurrentCulture.ClearCachedData(); CultureInfo.CurrentUICulture.ClearCachedData(); #endif @@ -103,11 +103,11 @@ public override void Before(MethodInfo methodUnderTest) /// The method under test public override void After(MethodInfo methodUnderTest) { -#if NET46 || NET461 || NETCOREAPP2_0 +#if NET46 || NETCOREAPP2_0 CultureInfo.CurrentCulture = _originalCulture; CultureInfo.CurrentUICulture = _originalUICulture; -#if NET46 || NET461 +#if NET46 CultureInfo.CurrentCulture.ClearCachedData(); CultureInfo.CurrentUICulture.ClearCachedData(); #endif diff --git a/src/Test/Utilities/Portable/Compilation/OperationTreeVerifier.cs b/src/Test/Utilities/Portable/Compilation/OperationTreeVerifier.cs index 8529fa9cf8a80..463854f3b879f 100644 --- a/src/Test/Utilities/Portable/Compilation/OperationTreeVerifier.cs +++ b/src/Test/Utilities/Portable/Compilation/OperationTreeVerifier.cs @@ -1423,7 +1423,23 @@ public override void VisitLocalFunction(ILocalFunctionOperation operation) LogString(")"); LogCommonPropertiesAndNewLine(operation); - Visit(operation.Body); + if (operation.Body != null) + { + if (operation.IgnoredBody != null) + { + Visit(operation.Body, "Body"); + Visit(operation.IgnoredBody, "IgnoredBody"); + + } + else + { + Visit(operation.Body); + } + } + else + { + Assert.Null(operation.IgnoredBody); + } } private void LogCaseClauseCommon(ICaseClauseOperation operation) diff --git a/src/Test/Utilities/Portable/Compilation/RuntimeUtilities.cs b/src/Test/Utilities/Portable/Compilation/RuntimeUtilities.cs index f71e02b10fcdc..c29a6a0b136df 100644 --- a/src/Test/Utilities/Portable/Compilation/RuntimeUtilities.cs +++ b/src/Test/Utilities/Portable/Compilation/RuntimeUtilities.cs @@ -15,7 +15,7 @@ public static partial class RuntimeUtilities { internal static BuildPaths CreateBuildPaths(string workingDirectory) { -#if NET461 || NET46 +#if NET46 return new BuildPaths( clientDir: Path.GetDirectoryName(typeof(BuildPathsUtil).Assembly.Location), workingDir: workingDirectory, @@ -32,7 +32,7 @@ internal static BuildPaths CreateBuildPaths(string workingDirectory) internal static IRuntimeEnvironmentFactory GetRuntimeEnvironmentFactory() { -#if NET461 || NET46 +#if NET46 return new Roslyn.Test.Utilities.Desktop.DesktopRuntimeEnvironmentFactory(); #elif NETCOREAPP2_0 return new Roslyn.Test.Utilities.CoreClr.CoreCLRRuntimeEnvironmentFactory(); @@ -45,7 +45,7 @@ internal static IRuntimeEnvironmentFactory GetRuntimeEnvironmentFactory() internal static AnalyzerAssemblyLoader CreateAnalyzerAssemblyLoader() { -#if NET461 || NET46 +#if NET46 return new DesktopAnalyzerAssemblyLoader(); #else return new ThrowingAnalyzerAssemblyLoader(); @@ -57,7 +57,7 @@ internal static AnalyzerAssemblyLoader CreateAnalyzerAssemblyLoader() /// internal static string GetAssemblyLocation(Type type) { -#if NET461 || NET46 || NETCOREAPP2_0 +#if NET46 || NETCOREAPP2_0 return type.GetTypeInfo().Assembly.Location; #elif NETSTANDARD1_3 throw new NotSupportedException(); diff --git a/src/Test/Utilities/Portable/Compilation/TestOperationVisitor.cs b/src/Test/Utilities/Portable/Compilation/TestOperationVisitor.cs index 07498388446a3..73e003cac4868 100644 --- a/src/Test/Utilities/Portable/Compilation/TestOperationVisitor.cs +++ b/src/Test/Utilities/Portable/Compilation/TestOperationVisitor.cs @@ -717,10 +717,21 @@ public override void VisitLocalFunction(ILocalFunctionOperation operation) if (operation.Body != null) { - Assert.Same(operation.Body, operation.Children.Single()); + var children = operation.Children.ToImmutableArray(); + Assert.Same(operation.Body, children[0]); + if (operation.IgnoredBody != null) + { + Assert.Same(operation.IgnoredBody, children[1]); + Assert.Equal(2, children.Length); + } + else + { + Assert.Equal(1, children.Length); + } } else { + Assert.Null(operation.IgnoredBody); Assert.Empty(operation.Children); } } diff --git a/src/Test/Utilities/Portable/Platform/Desktop/AppDomainAssemblyCache.cs b/src/Test/Utilities/Portable/Platform/Desktop/AppDomainAssemblyCache.cs index dde05960b6847..0327380279f43 100644 --- a/src/Test/Utilities/Portable/Platform/Desktop/AppDomainAssemblyCache.cs +++ b/src/Test/Utilities/Portable/Platform/Desktop/AppDomainAssemblyCache.cs @@ -1,6 +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. -#if NET461 || NET46 +#if NET46 using System; using System.Collections.Concurrent; diff --git a/src/Test/Utilities/Portable/Platform/Desktop/AppDomainUtils.cs b/src/Test/Utilities/Portable/Platform/Desktop/AppDomainUtils.cs index 814935f1bb480..27d89ad49fad2 100644 --- a/src/Test/Utilities/Portable/Platform/Desktop/AppDomainUtils.cs +++ b/src/Test/Utilities/Portable/Platform/Desktop/AppDomainUtils.cs @@ -1,5 +1,5 @@ // Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -#if NET461 || NET46 +#if NET46 using System; using System.IO; using System.Reflection; diff --git a/src/Test/Utilities/Portable/Platform/Desktop/CLRHelpers.cs b/src/Test/Utilities/Portable/Platform/Desktop/CLRHelpers.cs index 8fa48d117934b..29eabe54ee056 100644 --- a/src/Test/Utilities/Portable/Platform/Desktop/CLRHelpers.cs +++ b/src/Test/Utilities/Portable/Platform/Desktop/CLRHelpers.cs @@ -1,5 +1,5 @@ // Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -#if NET461 || NET46 +#if NET46 using System; using System.Collections.Generic; diff --git a/src/Test/Utilities/Portable/Platform/Desktop/ConditionalFactAttribute.cs b/src/Test/Utilities/Portable/Platform/Desktop/ConditionalFactAttribute.cs index a7aed56ce180f..0a531eadffe89 100644 --- a/src/Test/Utilities/Portable/Platform/Desktop/ConditionalFactAttribute.cs +++ b/src/Test/Utilities/Portable/Platform/Desktop/ConditionalFactAttribute.cs @@ -1,5 +1,5 @@ // Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -#if NET461 || NET46 +#if NET46 using System; using System.Drawing; diff --git a/src/Test/Utilities/Portable/Platform/Desktop/DesktopRuntimeEnvironment.cs b/src/Test/Utilities/Portable/Platform/Desktop/DesktopRuntimeEnvironment.cs index 423695e37a8d8..cfe20c905bc31 100644 --- a/src/Test/Utilities/Portable/Platform/Desktop/DesktopRuntimeEnvironment.cs +++ b/src/Test/Utilities/Portable/Platform/Desktop/DesktopRuntimeEnvironment.cs @@ -1,6 +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. -#if NET461 || NET46 +#if NET46 using System; using System.Collections.Generic; diff --git a/src/Test/Utilities/Portable/Platform/Desktop/DesktopRuntimeEnvironmentFactory.cs b/src/Test/Utilities/Portable/Platform/Desktop/DesktopRuntimeEnvironmentFactory.cs index 39903de438568..59d30bd77476e 100644 --- a/src/Test/Utilities/Portable/Platform/Desktop/DesktopRuntimeEnvironmentFactory.cs +++ b/src/Test/Utilities/Portable/Platform/Desktop/DesktopRuntimeEnvironmentFactory.cs @@ -1,4 +1,4 @@ -#if NET461 || NET46 +#if NET46 using System.Collections.Generic; using Roslyn.Test.Utilities; diff --git a/src/Test/Utilities/Portable/Platform/Desktop/DesktopRuntimeUtil.cs b/src/Test/Utilities/Portable/Platform/Desktop/DesktopRuntimeUtil.cs index 104048e73190e..33ee2dc9a719d 100644 --- a/src/Test/Utilities/Portable/Platform/Desktop/DesktopRuntimeUtil.cs +++ b/src/Test/Utilities/Portable/Platform/Desktop/DesktopRuntimeUtil.cs @@ -1,4 +1,4 @@ -#if NET461 || NET46 +#if NET46 using System; using System.Collections.Generic; using System.Collections.Immutable; diff --git a/src/Test/Utilities/Portable/Platform/Desktop/ErrorDiagnostics.cs b/src/Test/Utilities/Portable/Platform/Desktop/ErrorDiagnostics.cs index ae3733c44e322..765c600de6173 100644 --- a/src/Test/Utilities/Portable/Platform/Desktop/ErrorDiagnostics.cs +++ b/src/Test/Utilities/Portable/Platform/Desktop/ErrorDiagnostics.cs @@ -1,6 +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. -#if NET461 || NET46 +#if NET46 using System; using System.Collections.Generic; using System.Linq; diff --git a/src/Test/Utilities/Portable/Platform/Desktop/Exceptions.cs b/src/Test/Utilities/Portable/Platform/Desktop/Exceptions.cs index e8f6888d14154..d2a20d17ab1dd 100644 --- a/src/Test/Utilities/Portable/Platform/Desktop/Exceptions.cs +++ b/src/Test/Utilities/Portable/Platform/Desktop/Exceptions.cs @@ -1,6 +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. -#if NET461 || NET46 +#if NET46 using System; using System.Collections.Generic; using System.Runtime.Serialization; diff --git a/src/Test/Utilities/Portable/Platform/Desktop/Extensions.cs b/src/Test/Utilities/Portable/Platform/Desktop/Extensions.cs index 2e4a573e959d6..b46ecff573254 100644 --- a/src/Test/Utilities/Portable/Platform/Desktop/Extensions.cs +++ b/src/Test/Utilities/Portable/Platform/Desktop/Extensions.cs @@ -1,6 +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. -#if NET461 || NET46 +#if NET46 using System; using System.Collections.Concurrent; using System.Collections.Generic; diff --git a/src/Test/Utilities/Portable/Platform/Desktop/RuntimeAssemblyManager.cs b/src/Test/Utilities/Portable/Platform/Desktop/RuntimeAssemblyManager.cs index 5cd757a3b1718..f2d15c250c49e 100644 --- a/src/Test/Utilities/Portable/Platform/Desktop/RuntimeAssemblyManager.cs +++ b/src/Test/Utilities/Portable/Platform/Desktop/RuntimeAssemblyManager.cs @@ -1,6 +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. -#if NET461 || NET46 +#if NET46 using System; using System.Collections.Generic; using System.Collections.Immutable; diff --git a/src/Test/Utilities/Portable/Platform/Desktop/RuntimeModuleData.cs b/src/Test/Utilities/Portable/Platform/Desktop/RuntimeModuleData.cs index a0c1006ae77e3..ef7e73ecc9805 100644 --- a/src/Test/Utilities/Portable/Platform/Desktop/RuntimeModuleData.cs +++ b/src/Test/Utilities/Portable/Platform/Desktop/RuntimeModuleData.cs @@ -1,5 +1,5 @@ // Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -#if NET461 || NET46 +#if NET46 using System; using System.Collections.Concurrent; diff --git a/src/Test/Utilities/Portable/Platform/Desktop/TestHelpers.cs b/src/Test/Utilities/Portable/Platform/Desktop/TestHelpers.cs index 2bd4296b7c7bf..c853cdcaa4a03 100644 --- a/src/Test/Utilities/Portable/Platform/Desktop/TestHelpers.cs +++ b/src/Test/Utilities/Portable/Platform/Desktop/TestHelpers.cs @@ -1,4 +1,4 @@ -#if NET461 || NET46 +#if NET46 using System; using System.Collections.Generic; using System.Collections.Immutable; diff --git a/src/Test/Utilities/Portable/ThrowingTraceListener.cs b/src/Test/Utilities/Portable/ThrowingTraceListener.cs index 070ddb8027177..46ada88856eb0 100644 --- a/src/Test/Utilities/Portable/ThrowingTraceListener.cs +++ b/src/Test/Utilities/Portable/ThrowingTraceListener.cs @@ -21,7 +21,7 @@ public sealed class ThrowingTraceListener : TraceListener { public override void Fail(string message, string detailMessage) { - throw new DebugAssertFailureException(message + Environment.NewLine + detailMessage); + throw new InvalidOperationException(message + Environment.NewLine + detailMessage); } public override void Write(object o) @@ -55,12 +55,5 @@ public override void WriteLine(string message) public override void WriteLine(string message, string category) { } - - public class DebugAssertFailureException : Exception - { - public DebugAssertFailureException() { } - public DebugAssertFailureException(string message) : base(message) { } - public DebugAssertFailureException(string message, Exception inner) : base(message, inner) { } - } } } diff --git a/src/Test/Utilities/Portable/Traits/Traits.cs b/src/Test/Utilities/Portable/Traits/Traits.cs index 0d580d5467223..3e5f506a708de 100644 --- a/src/Test/Utilities/Portable/Traits/Traits.cs +++ b/src/Test/Utilities/Portable/Traits/Traits.cs @@ -50,7 +50,9 @@ public static class Features public const string CodeActionsConvertToInterpolatedString = "CodeActions.ConvertToInterpolatedString"; public const string CodeActionsConvertToIterator = "CodeActions.ConvertToIterator"; public const string CodeActionsConvertForToForEach = "CodeActions.ConvertForToForEach"; + public const string CodeActionsConvertForEachToFor = "CodeActions.ConvertForEachToFor"; public const string CodeActionsConvertIfToSwitch = "CodeActions.ConvertIfToSwitch"; + public const string CodeActionsConvertQueryToForEach = "CodeActions.ConvertQueryToForEach"; public const string CodeActionsCorrectExitContinue = "CodeActions.CorrectExitContinue"; public const string CodeActionsCorrectFunctionReturnType = "CodeActions.CorrectFunctionReturnType"; public const string CodeActionsCorrectNextControlVariable = "CodeActions.CorrectNextControlVariable"; diff --git a/src/VisualStudio/CSharp/Repl/CSharpVisualStudioRepl.csproj b/src/VisualStudio/CSharp/Repl/CSharpVisualStudioRepl.csproj index 62c975f3d9419..81bb3518d96bb 100644 --- a/src/VisualStudio/CSharp/Repl/CSharpVisualStudioRepl.csproj +++ b/src/VisualStudio/CSharp/Repl/CSharpVisualStudioRepl.csproj @@ -11,7 +11,7 @@ false false true - net461 + net46 diff --git a/src/VisualStudio/CSharp/Test/CSharpVisualStudioTest.csproj b/src/VisualStudio/CSharp/Test/CSharpVisualStudioTest.csproj index f74ddcaa5bbfc..cf9a1e61fc8e3 100644 --- a/src/VisualStudio/CSharp/Test/CSharpVisualStudioTest.csproj +++ b/src/VisualStudio/CSharp/Test/CSharpVisualStudioTest.csproj @@ -8,7 +8,7 @@ Library Roslyn.VisualStudio.CSharp.UnitTests Roslyn.VisualStudio.CSharp.UnitTests - net461 + net46 $(RoslynDesktopRuntimeIdentifier) UnitTest diff --git a/src/VisualStudio/CSharp/Test/CallHierarchy/CSharpCallHierarchyTests.cs b/src/VisualStudio/CSharp/Test/CallHierarchy/CSharpCallHierarchyTests.cs index d7b3538d958b8..c3c416a7bed13 100644 --- a/src/VisualStudio/CSharp/Test/CallHierarchy/CSharpCallHierarchyTests.cs +++ b/src/VisualStudio/CSharp/Test/CallHierarchy/CSharpCallHierarchyTests.cs @@ -8,6 +8,7 @@ namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.CallHierarchy { + [UseExportProvider] public class CSharpCallHierarchyTests { [WpfFact, Trait(Traits.Feature, Traits.Features.CallHierarchy)] diff --git a/src/VisualStudio/CSharp/Test/CodeModel/AbstractFileCodeElementTests.cs b/src/VisualStudio/CSharp/Test/CodeModel/AbstractFileCodeElementTests.cs index 8460e26ab1a33..f5911de2c7f13 100644 --- a/src/VisualStudio/CSharp/Test/CodeModel/AbstractFileCodeElementTests.cs +++ b/src/VisualStudio/CSharp/Test/CodeModel/AbstractFileCodeElementTests.cs @@ -4,6 +4,7 @@ using System.Linq; using EnvDTE; using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces; +using Microsoft.CodeAnalysis.Test.Utilities; using Roslyn.Test.Utilities; namespace Microsoft.VisualStudio.LanguageServices.CSharp.UnitTests.CodeModel @@ -12,18 +13,33 @@ namespace Microsoft.VisualStudio.LanguageServices.CSharp.UnitTests.CodeModel /// Base class of a all test-containing classes. Automatically creates a FileCodeModel for testing with the given /// file. /// + [UseExportProvider] public abstract class AbstractFileCodeElementTests : IDisposable { - private readonly Tuple _workspaceAndCodeModel; + private readonly string _contents; + private Tuple _workspaceAndCodeModel; + + public AbstractFileCodeElementTests(string contents) + { + _contents = contents; + } + + public Tuple WorkspaceAndCodeModel + { + get + { + return _workspaceAndCodeModel ?? (_workspaceAndCodeModel = CreateWorkspaceAndFileCodeModelAsync(_contents)); + } + } protected TestWorkspace GetWorkspace() { - return _workspaceAndCodeModel.Item1; + return WorkspaceAndCodeModel.Item1; } protected FileCodeModel GetCodeModel() { - return _workspaceAndCodeModel.Item2; + return WorkspaceAndCodeModel.Item2; } protected Microsoft.CodeAnalysis.Solution GetCurrentSolution() @@ -35,11 +51,6 @@ protected Microsoft.CodeAnalysis.Project GetCurrentProject() protected Microsoft.CodeAnalysis.Document GetCurrentDocument() => GetCurrentProject().Documents.Single(); - public AbstractFileCodeElementTests(string contents) - { - _workspaceAndCodeModel = CreateWorkspaceAndFileCodeModelAsync(contents); - } - protected static Tuple CreateWorkspaceAndFileCodeModelAsync(string file) => FileCodeModelTestHelpers.CreateWorkspaceAndFileCodeModel(file); diff --git a/src/VisualStudio/CSharp/Test/CodeModel/FileCodeModelTestHelpers.cs b/src/VisualStudio/CSharp/Test/CodeModel/FileCodeModelTestHelpers.cs index 7a2de3c8df597..90e2056951a34 100644 --- a/src/VisualStudio/CSharp/Test/CodeModel/FileCodeModelTestHelpers.cs +++ b/src/VisualStudio/CSharp/Test/CodeModel/FileCodeModelTestHelpers.cs @@ -3,7 +3,6 @@ using System; using System.Linq; using System.Runtime.ExceptionServices; -using System.Threading.Tasks; using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces; using Microsoft.VisualStudio.LanguageServices.Implementation.CodeModel; using Microsoft.VisualStudio.LanguageServices.Implementation.Interop; @@ -22,7 +21,7 @@ internal static class FileCodeModelTestHelpers [HandleProcessCorruptedStateExceptions] public static Tuple CreateWorkspaceAndFileCodeModel(string file) { - var workspace = TestWorkspace.CreateCSharp(file, exportProvider: VisualStudioTestExportProvider.ExportProvider); + var workspace = TestWorkspace.CreateCSharp(file, exportProvider: VisualStudioTestExportProvider.Factory.CreateExportProvider()); try { diff --git a/src/VisualStudio/CSharp/Test/CodeModel/VisualStudioTestExportProvider.cs b/src/VisualStudio/CSharp/Test/CodeModel/VisualStudioTestExportProvider.cs index 99e984320b7ea..f3279938bd9ab 100644 --- a/src/VisualStudio/CSharp/Test/CodeModel/VisualStudioTestExportProvider.cs +++ b/src/VisualStudio/CSharp/Test/CodeModel/VisualStudioTestExportProvider.cs @@ -1,8 +1,7 @@ // Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using System; -using System.Linq; using Microsoft.CodeAnalysis.Editor.UnitTests; +using Microsoft.CodeAnalysis.Test.Utilities; using Microsoft.VisualStudio.Composition; using Microsoft.VisualStudio.LanguageServices.CSharp.CodeModel; @@ -10,16 +9,13 @@ namespace Microsoft.VisualStudio.LanguageServices.CSharp.UnitTests.CodeModel { public static class VisualStudioTestExportProvider { - public static readonly ExportProvider ExportProvider; - public static readonly ComposableCatalog PartCatalog; + public static readonly IExportProviderFactory Factory; static VisualStudioTestExportProvider() { - PartCatalog = + Factory = ExportProviderCache.GetOrCreateExportProviderFactory( TestExportProvider.EntireAssemblyCatalogWithCSharpAndVisualBasic.WithParts( - MinimalTestExportProvider.CreateAssemblyCatalog(typeof(CSharpCodeModelService).Assembly)); - - ExportProvider = MinimalTestExportProvider.CreateExportProvider(PartCatalog); + ExportProviderCache.GetOrCreateAssemblyCatalog(typeof(CSharpCodeModelService).Assembly))); } } } diff --git a/src/VisualStudio/CSharp/Test/Debugging/DataTipInfoGetterTests.cs b/src/VisualStudio/CSharp/Test/Debugging/DataTipInfoGetterTests.cs index dbec839c5d1ff..50aa0113e1721 100644 --- a/src/VisualStudio/CSharp/Test/Debugging/DataTipInfoGetterTests.cs +++ b/src/VisualStudio/CSharp/Test/Debugging/DataTipInfoGetterTests.cs @@ -15,6 +15,7 @@ namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Debugging { + [UseExportProvider] public class DataTipInfoGetterTests { private async Task TestAsync(string markup, string expectedText = null) diff --git a/src/VisualStudio/CSharp/Test/Debugging/LocationInfoGetterTests.cs b/src/VisualStudio/CSharp/Test/Debugging/LocationInfoGetterTests.cs index a131cf36ab7a2..ff6db39c12edc 100644 --- a/src/VisualStudio/CSharp/Test/Debugging/LocationInfoGetterTests.cs +++ b/src/VisualStudio/CSharp/Test/Debugging/LocationInfoGetterTests.cs @@ -12,6 +12,7 @@ namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Debugging { + [UseExportProvider] public class LocationInfoGetterTests { private async Task TestAsync(string markup, string expectedName, int expectedLineOffset, CSharpParseOptions parseOptions = null) diff --git a/src/VisualStudio/CSharp/Test/Debugging/NameResolverTests.cs b/src/VisualStudio/CSharp/Test/Debugging/NameResolverTests.cs index 9aa46321fdfd5..2a664be7b14b5 100644 --- a/src/VisualStudio/CSharp/Test/Debugging/NameResolverTests.cs +++ b/src/VisualStudio/CSharp/Test/Debugging/NameResolverTests.cs @@ -10,6 +10,7 @@ namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Debugging { + [UseExportProvider] public class NameResolverTests { private async Task TestAsync(string text, string searchText, params string[] expectedNames) diff --git a/src/VisualStudio/CSharp/Test/Debugging/ProximityExpressionsGetterTests.cs b/src/VisualStudio/CSharp/Test/Debugging/ProximityExpressionsGetterTests.cs index 1b0b8ba1aadac..e72e924326af0 100644 --- a/src/VisualStudio/CSharp/Test/Debugging/ProximityExpressionsGetterTests.cs +++ b/src/VisualStudio/CSharp/Test/Debugging/ProximityExpressionsGetterTests.cs @@ -16,6 +16,7 @@ namespace Microsoft.CodeAnalysis.CSharp.UnitTests.Debugging { + [UseExportProvider] public partial class ProximityExpressionsGetterTests { private SyntaxTree GetTree() diff --git a/src/VisualStudio/CSharp/Test/DesignerAttribute/DesignerAttributeServiceTests.cs b/src/VisualStudio/CSharp/Test/DesignerAttribute/DesignerAttributeServiceTests.cs index 7817ffe2f6902..7e1d03564abaa 100644 --- a/src/VisualStudio/CSharp/Test/DesignerAttribute/DesignerAttributeServiceTests.cs +++ b/src/VisualStudio/CSharp/Test/DesignerAttribute/DesignerAttributeServiceTests.cs @@ -6,12 +6,14 @@ using Microsoft.CodeAnalysis.DesignerAttributes; using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces; using Microsoft.CodeAnalysis.Shared.Extensions; +using Microsoft.CodeAnalysis.Test.Utilities; using Microsoft.CodeAnalysis.Test.Utilities.RemoteHost; using Roslyn.Utilities; using Xunit; namespace Microsoft.VisualStudio.LanguageServices.CSharp.UnitTests.DesignerAttributes { + [UseExportProvider] public class DesignerAttributeServiceTests { [Fact] diff --git a/src/VisualStudio/CSharp/Test/EventHookup/EventHookupCommandHandlerTests.cs b/src/VisualStudio/CSharp/Test/EventHookup/EventHookupCommandHandlerTests.cs index 8d986ca3c2efa..bc1eb2f40bb15 100644 --- a/src/VisualStudio/CSharp/Test/EventHookup/EventHookupCommandHandlerTests.cs +++ b/src/VisualStudio/CSharp/Test/EventHookup/EventHookupCommandHandlerTests.cs @@ -10,6 +10,7 @@ namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.EventHookup { + [UseExportProvider] public class EventHookupCommandHandlerTests { [WpfFact, Trait(Traits.Feature, Traits.Features.EventHookup)] diff --git a/src/VisualStudio/CSharp/Test/EventHookup/EventHookupTestState.cs b/src/VisualStudio/CSharp/Test/EventHookup/EventHookupTestState.cs index dc5c7ff925e87..df58c0510f207 100644 --- a/src/VisualStudio/CSharp/Test/EventHookup/EventHookupTestState.cs +++ b/src/VisualStudio/CSharp/Test/EventHookup/EventHookupTestState.cs @@ -10,6 +10,7 @@ using Microsoft.CodeAnalysis.Editor.UnitTests.Extensions; using Microsoft.CodeAnalysis.Options; using Microsoft.CodeAnalysis.Shared.TestHooks; +using Microsoft.CodeAnalysis.Test.Utilities; using Microsoft.VisualStudio.Composition; using Microsoft.VisualStudio.Language.Intellisense; using Roslyn.Utilities; @@ -37,7 +38,7 @@ public EventHookupTestState(XElement workspaceElement, IDictionary options = null) diff --git a/src/VisualStudio/CSharp/Test/F1Help/F1HelpTests.cs b/src/VisualStudio/CSharp/Test/F1Help/F1HelpTests.cs index 9e1ecff840593..9832042225e56 100644 --- a/src/VisualStudio/CSharp/Test/F1Help/F1HelpTests.cs +++ b/src/VisualStudio/CSharp/Test/F1Help/F1HelpTests.cs @@ -12,6 +12,7 @@ namespace Microsoft.VisualStudio.LanguageServices.CSharp.UnitTests.F1Help { + [UseExportProvider] public class F1HelpTests { private async Task TestAsync(string markup, string expectedText) diff --git a/src/VisualStudio/CSharp/Test/Interactive/Commands/InteractiveCommandHandlerTests.cs b/src/VisualStudio/CSharp/Test/Interactive/Commands/InteractiveCommandHandlerTests.cs index d477aae817670..bbd89eeb204f4 100644 --- a/src/VisualStudio/CSharp/Test/Interactive/Commands/InteractiveCommandHandlerTests.cs +++ b/src/VisualStudio/CSharp/Test/Interactive/Commands/InteractiveCommandHandlerTests.cs @@ -2,12 +2,14 @@ using System.Collections.Generic; using Microsoft.CodeAnalysis.Test.Utilities; +using Microsoft.VisualStudio.Composition; using Roslyn.Test.Utilities; using Xunit; using VSCommanding = Microsoft.VisualStudio.Commanding; namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Interactive.Commands { + [UseExportProvider] public class InteractiveCommandHandlerTests { private const string Caret = "$$"; @@ -36,27 +38,34 @@ void goo() { [Trait(Traits.Feature, Traits.Features.Interactive)] public void TestExecuteInInteractiveWithoutSelection() { - AssertExecuteInInteractive(Caret, new string[0]); + var exportProvider = InteractiveWindowTestHost.ExportProviderFactory.CreateExportProvider(); + + AssertExecuteInInteractive(exportProvider, Caret, new string[0]); AssertExecuteInInteractive( + exportProvider, @"var x = 1; $$ var y = 2;", new string[0]); - AssertExecuteInInteractive(ExampleCode1 + Caret, ExampleCode1); - AssertExecuteInInteractive(ExampleCode1.Insert(3, Caret), ExampleCode1); - AssertExecuteInInteractive(ExampleCode2 + Caret, ExampleCode2Line2); - AssertExecuteInInteractive(ExampleMultiline, ExpectedMultilineSelection); + AssertExecuteInInteractive(exportProvider, ExampleCode1 + Caret, ExampleCode1); + AssertExecuteInInteractive(exportProvider, ExampleCode1.Insert(3, Caret), ExampleCode1); + AssertExecuteInInteractive(exportProvider, ExampleCode2 + Caret, ExampleCode2Line2); + AssertExecuteInInteractive(exportProvider, ExampleMultiline, ExpectedMultilineSelection); } [WpfFact] [Trait(Traits.Feature, Traits.Features.Interactive)] public void TestExecuteInInteractiveWithEmptyBuffer() { + var exportProvider = InteractiveWindowTestHost.ExportProviderFactory.CreateExportProvider(); + AssertExecuteInInteractive( + exportProvider, @"{|Selection:|}var x = 1; {|Selection:$$|}var y = 2;", new string[0]); - AssertExecuteInInteractive($@"{{|Selection:{ExampleCode1}$$|}}", ExampleCode1); - AssertExecuteInInteractive($@"{{|Selection:{ExampleCode2}$$|}}", ExampleCode2); + AssertExecuteInInteractive(exportProvider, $@"{{|Selection:{ExampleCode1}$$|}}", ExampleCode1); + AssertExecuteInInteractive(exportProvider, $@"{{|Selection:{ExampleCode2}$$|}}", ExampleCode2); AssertExecuteInInteractive( + exportProvider, $@"var o = new object[] {{ 1, 2, 3 }}; Console.WriteLine(o); {{|Selection:{ExampleCode2}$$|}} @@ -68,18 +77,24 @@ public void TestExecuteInInteractiveWithEmptyBuffer() [Trait(Traits.Feature, Traits.Features.Interactive)] public void TestExecuteInInteractiveWithBoxSelection() { + var exportProvider = InteractiveWindowTestHost.ExportProviderFactory.CreateExportProvider(); + string expectedBoxSubmissionResult = @"int x; int y;"; AssertExecuteInInteractive( + exportProvider, $@"some text {{|Selection:$$int x;|}} also here text some {{|Selection:int y;|}} here also", expectedBoxSubmissionResult); AssertExecuteInInteractive( + exportProvider, $@"some text {{|Selection:int x;$$|}} also here text some {{|Selection:int y;|}} here also", expectedBoxSubmissionResult); AssertExecuteInInteractive( + exportProvider, $@"some text {{|Selection:int x;|}} also here text some {{|Selection:$$int y;|}} here also", expectedBoxSubmissionResult); AssertExecuteInInteractive( + exportProvider, $@"some text {{|Selection:int x;|}} also here text some {{|Selection:int y;$$|}} here also", expectedBoxSubmissionResult); } @@ -88,9 +103,12 @@ public void TestExecuteInInteractiveWithBoxSelection() [Trait(Traits.Feature, Traits.Features.Interactive)] public void TestExecuteInInteractiveWithNonEmptyBuffer() { + var exportProvider = InteractiveWindowTestHost.ExportProviderFactory.CreateExportProvider(); + // Execute in interactive clears the existing current buffer before execution. // Therefore `var x = 1;` will not be executed. AssertExecuteInInteractive( + exportProvider, @"{|Selection:var y = 2;$$|}", "var y = 2;", submissionBuffer: "var x = 1;"); @@ -99,6 +117,8 @@ public void TestExecuteInInteractiveWithNonEmptyBuffer() [WpfFact(Skip = "https://github.com/dotnet/roslyn/issues/23200")] public void TestExecuteInInteractiveWithDefines() { + var exportProvider = InteractiveWindowTestHost.ExportProviderFactory.CreateExportProvider(); + string exampleWithIfDirective = @"#if DEF public void $$Run() @@ -106,14 +126,14 @@ public void TestExecuteInInteractiveWithDefines() } #endif"; - AssertExecuteInInteractive(exampleWithIfDirective, + AssertExecuteInInteractive(exportProvider, exampleWithIfDirective, @"public void Run()"); string exampleWithDefine = $@"#define DEF {exampleWithIfDirective}"; - AssertExecuteInInteractive(exampleWithDefine, + AssertExecuteInInteractive(exportProvider, exampleWithDefine, @"public void Run() { }"); @@ -123,13 +143,17 @@ public void TestExecuteInInteractiveWithDefines() [Trait(Traits.Feature, Traits.Features.Interactive)] public void TestCopyToInteractiveWithoutSelection() { - AssertCopyToInteractive(Caret, ""); - AssertCopyToInteractive($"{ExampleCode2}$$", ExampleCode2Line2); + var exportProvider = InteractiveWindowTestHost.ExportProviderFactory.CreateExportProvider(); + + AssertCopyToInteractive(exportProvider, Caret, ""); + AssertCopyToInteractive(exportProvider, $"{ExampleCode2}$$", ExampleCode2Line2); AssertCopyToInteractive( + exportProvider, code: ExampleCode2 + Caret, submissionBuffer: ExampleCode1, expectedBufferText: ExampleCode1 + "\r\n" + ExampleCode2Line2); AssertCopyToInteractive( + exportProvider, code: ExampleCode2 + Caret, submissionBuffer: "x = 2;", expectedBufferText: "x = 2;\r\n" + ExampleCode2Line2); @@ -139,24 +163,29 @@ public void TestCopyToInteractiveWithoutSelection() [Trait(Traits.Feature, Traits.Features.Interactive)] public void TestCopyToInteractive() { - AssertCopyToInteractive($"{{|Selection:{ExampleCode2}$$|}}", ExampleCode2); + var exportProvider = InteractiveWindowTestHost.ExportProviderFactory.CreateExportProvider(); + + AssertCopyToInteractive(exportProvider, $"{{|Selection:{ExampleCode2}$$|}}", ExampleCode2); } [WpfFact] [Trait(Traits.Feature, Traits.Features.Interactive)] public void TestCopyToInteractiveWithNonEmptyBuffer() { + var exportProvider = InteractiveWindowTestHost.ExportProviderFactory.CreateExportProvider(); + // Copy to interactive does not clear the existing buffer. // Therefore `var x = 1;` will still be present in the final buffer. AssertCopyToInteractive( + exportProvider, $"{{|Selection:{ExampleCode2}$$|}}", $"var x = 1;\r\n{ExampleCode2}", submissionBuffer: "var x = 1;"); } - private static void AssertCopyToInteractive(string code, string expectedBufferText, string submissionBuffer = null) + private static void AssertCopyToInteractive(ExportProvider exportProvider, string code, string expectedBufferText, string submissionBuffer = null) { - using (var workspace = InteractiveWindowCommandHandlerTestState.CreateTestState(code)) + using (var workspace = InteractiveWindowCommandHandlerTestState.CreateTestState(exportProvider, code)) { PrepareSubmissionBuffer(submissionBuffer, workspace); workspace.SendCopyToInteractive(); @@ -164,17 +193,17 @@ private static void AssertCopyToInteractive(string code, string expectedBufferTe } } - private static void AssertExecuteInInteractive(string code, string expectedSubmission, string submissionBuffer = null) + private static void AssertExecuteInInteractive(ExportProvider exportProvider, string code, string expectedSubmission, string submissionBuffer = null) { - AssertExecuteInInteractive(code, new string[] { expectedSubmission }, submissionBuffer); + AssertExecuteInInteractive(exportProvider, code, new string[] { expectedSubmission }, submissionBuffer); } - private static void AssertExecuteInInteractive(string code, string[] expectedSubmissions, string submissionBuffer = null) + private static void AssertExecuteInInteractive(ExportProvider exportProvider, string code, string[] expectedSubmissions, string submissionBuffer = null) { List submissions = new List(); void appendSubmission(object _, string item) { submissions.Add(item.TrimEnd()); } - using (var workspace = InteractiveWindowCommandHandlerTestState.CreateTestState(code)) + using (var workspace = InteractiveWindowCommandHandlerTestState.CreateTestState(exportProvider, code)) { PrepareSubmissionBuffer(submissionBuffer, workspace); Assert.Equal(VSCommanding.CommandState.Available, workspace.GetStateForExecuteInInteractive()); diff --git a/src/VisualStudio/CSharp/Test/Interactive/Commands/InteractiveWindowCommandHandlerTestState.cs b/src/VisualStudio/CSharp/Test/Interactive/Commands/InteractiveWindowCommandHandlerTestState.cs index 07dab6e3d4df3..1150a876be82c 100644 --- a/src/VisualStudio/CSharp/Test/Interactive/Commands/InteractiveWindowCommandHandlerTestState.cs +++ b/src/VisualStudio/CSharp/Test/Interactive/Commands/InteractiveWindowCommandHandlerTestState.cs @@ -4,6 +4,7 @@ using Microsoft.CodeAnalysis.Editor.Interactive; using Microsoft.CodeAnalysis.Editor.UnitTests; using Microsoft.CodeAnalysis.Editor.UnitTests.Utilities; +using Microsoft.VisualStudio.Composition; using Microsoft.VisualStudio.Text; using Microsoft.VisualStudio.Text.Editor; using Microsoft.VisualStudio.Text.Editor.Commanding.Commands; @@ -35,10 +36,10 @@ internal class InteractiveWindowCommandHandlerTestState : AbstractCommandHandler private VSCommanding.ICommandHandler CopyToInteractiveCommandHandler => _commandHandler; - public InteractiveWindowCommandHandlerTestState(XElement workspaceElement) - : base(workspaceElement) + public InteractiveWindowCommandHandlerTestState(ExportProvider exportProvider, XElement workspaceElement) + : base(workspaceElement, exportProvider, workspaceKind: null) { - TestHost = new InteractiveWindowTestHost(); + TestHost = new InteractiveWindowTestHost(exportProvider); _commandHandler = new TestInteractiveCommandHandler( TestHost.Window, @@ -48,7 +49,7 @@ public InteractiveWindowCommandHandlerTestState(XElement workspaceElement) TestWaitIndicator.Default); } - public static InteractiveWindowCommandHandlerTestState CreateTestState(string markup) + public static InteractiveWindowCommandHandlerTestState CreateTestState(ExportProvider exportProvider, string markup) { var workspaceXml = XElement.Parse($@" @@ -58,7 +59,7 @@ public static InteractiveWindowCommandHandlerTestState CreateTestState(string ma "); - return new InteractiveWindowCommandHandlerTestState(workspaceXml); + return new InteractiveWindowCommandHandlerTestState(exportProvider, workspaceXml); } public void SendCopyToInteractive() diff --git a/src/VisualStudio/CSharp/Test/Interactive/Commands/ResetInteractiveTests.cs b/src/VisualStudio/CSharp/Test/Interactive/Commands/ResetInteractiveTests.cs index 838cd7fccb990..a2744dafcd7f7 100644 --- a/src/VisualStudio/CSharp/Test/Interactive/Commands/ResetInteractiveTests.cs +++ b/src/VisualStudio/CSharp/Test/Interactive/Commands/ResetInteractiveTests.cs @@ -13,6 +13,7 @@ namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Interactive.Commands { + [UseExportProvider] public class ResetInteractiveTests { private string WorkspaceXmlStr => @@ -36,7 +37,7 @@ class TestClass [Trait(Traits.Feature, Traits.Features.Interactive)] public void TestResetREPLWithProjectContext() { - using (var workspace = TestWorkspace.Create(WorkspaceXmlStr)) + using (var workspace = TestWorkspace.Create(WorkspaceXmlStr, exportProvider: InteractiveWindowTestHost.ExportProviderFactory.CreateExportProvider())) { var project = workspace.CurrentSolution.Projects.FirstOrDefault(p => p.AssemblyName == "ResetInteractiveTestsAssembly"); var document = project.Documents.FirstOrDefault(d => d.FilePath == "ResetInteractiveTestsDocument"); @@ -64,7 +65,7 @@ private async void AssertResetInteractive( expectedReferences = expectedReferences ?? new List(); expectedUsings = expectedUsings ?? new List(); - InteractiveWindowTestHost testHost = new InteractiveWindowTestHost(); + InteractiveWindowTestHost testHost = new InteractiveWindowTestHost(workspace.ExportProvider); List executedSubmissionCalls = new List(); void ExecuteSubmission(object _, string code) { executedSubmissionCalls.Add(code); } diff --git a/src/VisualStudio/CSharp/Test/Interactive/InteractiveWindowTestHost.cs b/src/VisualStudio/CSharp/Test/Interactive/InteractiveWindowTestHost.cs index 23188a7e4840d..534683296ab95 100644 --- a/src/VisualStudio/CSharp/Test/Interactive/InteractiveWindowTestHost.cs +++ b/src/VisualStudio/CSharp/Test/Interactive/InteractiveWindowTestHost.cs @@ -1,15 +1,16 @@ // Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; +using System.Collections.Generic; +using System.ComponentModel.Composition; using System.Linq; -using Microsoft.VisualStudio.Utilities; -using Microsoft.VisualStudio.InteractiveWindow; -using Microsoft.CodeAnalysis.Editor.UnitTests.Utilities; using Microsoft.CodeAnalysis.Editor.UnitTests; +using Microsoft.CodeAnalysis.Editor.UnitTests.Utilities; +using Microsoft.CodeAnalysis.Test.Utilities; using Microsoft.VisualStudio.Composition; +using Microsoft.VisualStudio.InteractiveWindow; using Microsoft.VisualStudio.Text.Utilities; -using System.Collections.Generic; -using System.ComponentModel.Composition; +using Microsoft.VisualStudio.Utilities; namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Interactive { @@ -20,13 +21,16 @@ public sealed class InteractiveWindowTestHost : IDisposable private readonly System.ComponentModel.Composition.Hosting.ExportProvider _exportProvider; - private static readonly Lazy s_lazyCatalog = new Lazy(() => - { - var assemblies = new[] { typeof(TestWaitIndicator).Assembly, typeof(TestInteractiveEvaluator).Assembly, typeof(IInteractiveWindow).Assembly } - .Concat(MinimalTestExportProvider.GetEditorAssemblies()); - return MinimalTestExportProvider.CreateAssemblyCatalog(assemblies); - }); - + internal static readonly IExportProviderFactory ExportProviderFactory = ExportProviderCache.GetOrCreateExportProviderFactory( + ExportProviderCache.GetOrCreateAssemblyCatalog( + new[] + { + typeof(TestWaitIndicator).Assembly, + typeof(TestInteractiveEvaluator).Assembly, + typeof(IInteractiveWindow).Assembly + } + .Concat(TestExportProvider.GetCSharpAndVisualBasicAssemblies()) + .Concat(MinimalTestExportProvider.GetEditorAssemblies()))); // Provide an export of ILoggingServiceInternal to work around https://devdiv.visualstudio.com/DevDiv/_workitems/edit/570290 [Export(typeof(ILoggingServiceInternal))] @@ -61,9 +65,9 @@ public void PostFault(string eventName, string description, Exception exceptionO } } - internal InteractiveWindowTestHost() + internal InteractiveWindowTestHost(ExportProvider exportProvider) { - _exportProvider = MinimalTestExportProvider.CreateExportProvider(s_lazyCatalog.Value).AsExportProvider(); + _exportProvider = exportProvider.AsExportProvider(); var contentTypeRegistryService = _exportProvider.GetExport().Value; Evaluator = new TestInteractiveEvaluator(); diff --git a/src/VisualStudio/CSharp/Test/Options/OptionViewModelTests.cs b/src/VisualStudio/CSharp/Test/Options/OptionViewModelTests.cs index 50d36542ee2da..8cde7779d2df1 100644 --- a/src/VisualStudio/CSharp/Test/Options/OptionViewModelTests.cs +++ b/src/VisualStudio/CSharp/Test/Options/OptionViewModelTests.cs @@ -14,6 +14,7 @@ namespace Roslyn.VisualStudio.CSharp.UnitTests.Options { + [UseExportProvider] public class OptionViewModelTests { private class MockServiceProvider : IServiceProvider diff --git a/src/VisualStudio/CSharp/Test/PersistentStorage/AbstractPersistentStorageTests.cs b/src/VisualStudio/CSharp/Test/PersistentStorage/AbstractPersistentStorageTests.cs index 2b29cc9ed0351..e75e0e7f6091f 100644 --- a/src/VisualStudio/CSharp/Test/PersistentStorage/AbstractPersistentStorageTests.cs +++ b/src/VisualStudio/CSharp/Test/PersistentStorage/AbstractPersistentStorageTests.cs @@ -12,11 +12,13 @@ using Microsoft.CodeAnalysis.SolutionSize; using Microsoft.CodeAnalysis.SQLite; using Microsoft.CodeAnalysis.Storage; +using Microsoft.CodeAnalysis.Test.Utilities; using Moq; using Xunit; namespace Microsoft.CodeAnalysis.UnitTests.WorkspaceServices { + [UseExportProvider] public abstract class AbstractPersistentStorageTests : IDisposable { private enum Size diff --git a/src/VisualStudio/CSharp/Test/PersistentStorage/SQLitePersistentStorageTests.cs b/src/VisualStudio/CSharp/Test/PersistentStorage/SQLitePersistentStorageTests.cs index 465ffea795267..262de16db1300 100644 --- a/src/VisualStudio/CSharp/Test/PersistentStorage/SQLitePersistentStorageTests.cs +++ b/src/VisualStudio/CSharp/Test/PersistentStorage/SQLitePersistentStorageTests.cs @@ -17,6 +17,11 @@ namespace Microsoft.CodeAnalysis.UnitTests.WorkspaceServices /// public class SQLitePersistentStorageTests : AbstractPersistentStorageTests { + static SQLitePersistentStorageTests() + { + Assert.True(SQLitePersistentStorageService.TryInitializeLibraries()); + } + internal override IPersistentStorageService GetStorageService(IPersistentStorageLocationService locationService, ISolutionSizeTracker solutionSizeTracker, IPersistentStorageFaultInjector faultInjector) => new SQLitePersistentStorageService(_persistentEnabledOptionService, locationService, solutionSizeTracker, faultInjector); diff --git a/src/VisualStudio/CSharp/Test/PersistentStorage/SolutionSizeTests.cs b/src/VisualStudio/CSharp/Test/PersistentStorage/SolutionSizeTests.cs index eb4d010ba7749..05f043121f959 100644 --- a/src/VisualStudio/CSharp/Test/PersistentStorage/SolutionSizeTests.cs +++ b/src/VisualStudio/CSharp/Test/PersistentStorage/SolutionSizeTests.cs @@ -5,11 +5,13 @@ using System.Threading.Tasks; using Microsoft.CodeAnalysis.SolutionCrawler; using Microsoft.CodeAnalysis.SolutionSize; +using Microsoft.CodeAnalysis.Test.Utilities; using Microsoft.CodeAnalysis.Text; using Xunit; namespace Microsoft.CodeAnalysis.UnitTests.WorkspaceServices { + [UseExportProvider] public class SolutionSizeTests { [Fact] diff --git a/src/VisualStudio/CSharp/Test/ProjectSystemShim/CPS/AnalyzersTests.cs b/src/VisualStudio/CSharp/Test/ProjectSystemShim/CPS/AnalyzersTests.cs index 62e413d9d4edb..35a7481579425 100644 --- a/src/VisualStudio/CSharp/Test/ProjectSystemShim/CPS/AnalyzersTests.cs +++ b/src/VisualStudio/CSharp/Test/ProjectSystemShim/CPS/AnalyzersTests.cs @@ -13,6 +13,7 @@ namespace Roslyn.VisualStudio.CSharp.UnitTests.ProjectSystemShim.CPS { + [UseExportProvider] public class AnalyzersTests { [WpfFact] diff --git a/src/VisualStudio/CSharp/Test/ProjectSystemShim/CPS/CSharpCompilerOptionsTests.cs b/src/VisualStudio/CSharp/Test/ProjectSystemShim/CPS/CSharpCompilerOptionsTests.cs index 0cac287889e6b..0eabca7b9b30e 100644 --- a/src/VisualStudio/CSharp/Test/ProjectSystemShim/CPS/CSharpCompilerOptionsTests.cs +++ b/src/VisualStudio/CSharp/Test/ProjectSystemShim/CPS/CSharpCompilerOptionsTests.cs @@ -12,6 +12,7 @@ namespace Roslyn.VisualStudio.CSharp.UnitTests.ProjectSystemShim.CPS { + [UseExportProvider] public class CSharpCompilerOptionsTests : TestBase { [WpfFact] diff --git a/src/VisualStudio/CSharp/Test/ProjectSystemShim/CPS/CSharpReferencesTests.cs b/src/VisualStudio/CSharp/Test/ProjectSystemShim/CPS/CSharpReferencesTests.cs index d9d4d28cd8a51..44ebac667e411 100644 --- a/src/VisualStudio/CSharp/Test/ProjectSystemShim/CPS/CSharpReferencesTests.cs +++ b/src/VisualStudio/CSharp/Test/ProjectSystemShim/CPS/CSharpReferencesTests.cs @@ -12,6 +12,7 @@ namespace Roslyn.VisualStudio.CSharp.UnitTests.ProjectSystemShim.CPS using Microsoft.VisualStudio.LanguageServices.ProjectSystem; using static CSharpHelpers; + [UseExportProvider] public class CSharpReferenceTests { [WpfFact] diff --git a/src/VisualStudio/CSharp/Test/ProjectSystemShim/CPS/SourceFileHandlingTests.cs b/src/VisualStudio/CSharp/Test/ProjectSystemShim/CPS/SourceFileHandlingTests.cs index 12c816cbceefa..bbe5f485c9476 100644 --- a/src/VisualStudio/CSharp/Test/ProjectSystemShim/CPS/SourceFileHandlingTests.cs +++ b/src/VisualStudio/CSharp/Test/ProjectSystemShim/CPS/SourceFileHandlingTests.cs @@ -10,6 +10,7 @@ namespace Roslyn.VisualStudio.CSharp.UnitTests.ProjectSystemShim.CPS { using static CSharpHelpers; + [UseExportProvider] public class SourceFileHandlingTests { [WpfFact] diff --git a/src/VisualStudio/CSharp/Test/ProjectSystemShim/LegacyProject/AnalyzersTests.cs b/src/VisualStudio/CSharp/Test/ProjectSystemShim/LegacyProject/AnalyzersTests.cs index 519bbcac7167a..d00c6e02d479a 100644 --- a/src/VisualStudio/CSharp/Test/ProjectSystemShim/LegacyProject/AnalyzersTests.cs +++ b/src/VisualStudio/CSharp/Test/ProjectSystemShim/LegacyProject/AnalyzersTests.cs @@ -13,6 +13,7 @@ namespace Roslyn.VisualStudio.CSharp.UnitTests.ProjectSystemShim.LegacyProject { + [UseExportProvider] public class AnalyzersTests { private sealed class DisposableFile : IDisposable diff --git a/src/VisualStudio/CSharp/Test/ProjectSystemShim/LegacyProject/CSharpCompilerOptionsTests.cs b/src/VisualStudio/CSharp/Test/ProjectSystemShim/LegacyProject/CSharpCompilerOptionsTests.cs index 75b72738e9107..8a4aa84d417a8 100644 --- a/src/VisualStudio/CSharp/Test/ProjectSystemShim/LegacyProject/CSharpCompilerOptionsTests.cs +++ b/src/VisualStudio/CSharp/Test/ProjectSystemShim/LegacyProject/CSharpCompilerOptionsTests.cs @@ -11,6 +11,7 @@ namespace Roslyn.VisualStudio.CSharp.UnitTests.ProjectSystemShim.LegacyProject { + [UseExportProvider] public class CSharpCompilerOptionsTests { [WpfFact] diff --git a/src/VisualStudio/CSharp/Test/ProjectSystemShim/LegacyProject/CSharpReferencesTests.cs b/src/VisualStudio/CSharp/Test/ProjectSystemShim/LegacyProject/CSharpReferencesTests.cs index ffe0886dfc1c0..ef46e8c8f1548 100644 --- a/src/VisualStudio/CSharp/Test/ProjectSystemShim/LegacyProject/CSharpReferencesTests.cs +++ b/src/VisualStudio/CSharp/Test/ProjectSystemShim/LegacyProject/CSharpReferencesTests.cs @@ -11,6 +11,7 @@ namespace Roslyn.VisualStudio.CSharp.UnitTests.ProjectSystemShim.LegacyProject { using static CSharpHelpers; + [UseExportProvider] public class CSharpReferenceTests { [WpfFact] diff --git a/src/VisualStudio/CSharp/Test/ProjectSystemShim/LegacyProject/SourceFileHandlingTests.cs b/src/VisualStudio/CSharp/Test/ProjectSystemShim/LegacyProject/SourceFileHandlingTests.cs index 7979e01d622e9..0b465a7ee39b2 100644 --- a/src/VisualStudio/CSharp/Test/ProjectSystemShim/LegacyProject/SourceFileHandlingTests.cs +++ b/src/VisualStudio/CSharp/Test/ProjectSystemShim/LegacyProject/SourceFileHandlingTests.cs @@ -8,6 +8,7 @@ namespace Roslyn.VisualStudio.CSharp.UnitTests.ProjectSystemShim.LegacyProject { + [UseExportProvider] public class SourceFileHandlingTests { [WpfFact] diff --git a/src/VisualStudio/CSharp/Test/ProjectSystemShim/LifetimeTests.cs b/src/VisualStudio/CSharp/Test/ProjectSystemShim/LifetimeTests.cs index 9a490b78fde68..d2739665e0736 100644 --- a/src/VisualStudio/CSharp/Test/ProjectSystemShim/LifetimeTests.cs +++ b/src/VisualStudio/CSharp/Test/ProjectSystemShim/LifetimeTests.cs @@ -7,6 +7,7 @@ namespace Roslyn.VisualStudio.CSharp.UnitTests.ProjectSystemShim { + [UseExportProvider] public class LifetimeTests { [WpfFact] diff --git a/src/VisualStudio/Core/Test.Next/Mocks/TestHostServices.cs b/src/VisualStudio/Core/Test.Next/Mocks/TestHostServices.cs index 621aa6c7b0c09..4ef13e9e93250 100644 --- a/src/VisualStudio/Core/Test.Next/Mocks/TestHostServices.cs +++ b/src/VisualStudio/Core/Test.Next/Mocks/TestHostServices.cs @@ -1,18 +1,15 @@ // Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using System.Composition; using Microsoft.CodeAnalysis.Editor.UnitTests; using Microsoft.CodeAnalysis.Host; using Microsoft.CodeAnalysis.Host.Mef; -using Microsoft.CodeAnalysis.Shared.TestHooks; +using Microsoft.CodeAnalysis.Test.Utilities; using Microsoft.VisualStudio.Composition; namespace Roslyn.VisualStudio.Next.UnitTests.Mocks { public static class TestHostServices { - public static readonly ExportProvider SharedExportProvider = CreateExportProvider(); - public static HostServices CreateHostServices(ExportProvider exportProvider = null) { exportProvider = exportProvider ?? CreateMinimalExportProvider(); @@ -21,16 +18,16 @@ public static HostServices CreateHostServices(ExportProvider exportProvider = nu public static ExportProvider CreateMinimalExportProvider() { - return MinimalTestExportProvider.CreateExportProvider( - ServiceTestExportProvider.CreateAssemblyCatalog() - .WithPart(typeof(InProcRemoteHostClientFactory))); + return ExportProviderCache + .GetOrCreateExportProviderFactory(ServiceTestExportProvider.CreateAssemblyCatalog().WithPart(typeof(InProcRemoteHostClientFactory))) + .CreateExportProvider(); } public static ExportProvider CreateExportProvider() { - return MinimalTestExportProvider.CreateExportProvider( - TestExportProvider.CreateAssemblyCatalogWithCSharpAndVisualBasic() - .WithPart(typeof(InProcRemoteHostClientFactory))); + return ExportProviderCache + .GetOrCreateExportProviderFactory(TestExportProvider.EntireAssemblyCatalogWithCSharpAndVisualBasic.WithPart(typeof(InProcRemoteHostClientFactory))) + .CreateExportProvider(); } } } diff --git a/src/VisualStudio/Core/Test.Next/Remote/RemoteHostClientServiceFactoryTests.cs b/src/VisualStudio/Core/Test.Next/Remote/RemoteHostClientServiceFactoryTests.cs index c51b19dc4b7ab..5c192420cd3c4 100644 --- a/src/VisualStudio/Core/Test.Next/Remote/RemoteHostClientServiceFactoryTests.cs +++ b/src/VisualStudio/Core/Test.Next/Remote/RemoteHostClientServiceFactoryTests.cs @@ -24,6 +24,7 @@ namespace Roslyn.VisualStudio.Next.UnitTests.Remote { + [UseExportProvider] public class RemoteHostClientServiceFactoryTests { [Fact, Trait(Traits.Feature, Traits.Features.RemoteHost)] diff --git a/src/VisualStudio/Core/Test.Next/Services/AssetServiceTests.cs b/src/VisualStudio/Core/Test.Next/Services/AssetServiceTests.cs index 5a8004ec5341b..6d3484dd92c0b 100644 --- a/src/VisualStudio/Core/Test.Next/Services/AssetServiceTests.cs +++ b/src/VisualStudio/Core/Test.Next/Services/AssetServiceTests.cs @@ -18,6 +18,7 @@ namespace Roslyn.VisualStudio.Next.UnitTests.Remote { + [UseExportProvider] public class AssetServiceTests { [Fact, Trait(Traits.Feature, Traits.Features.RemoteHost)] diff --git a/src/VisualStudio/Core/Test.Next/Services/ServiceHubServicesTests.cs b/src/VisualStudio/Core/Test.Next/Services/ServiceHubServicesTests.cs index 9ab6a6b48191e..83a902a91fad8 100644 --- a/src/VisualStudio/Core/Test.Next/Services/ServiceHubServicesTests.cs +++ b/src/VisualStudio/Core/Test.Next/Services/ServiceHubServicesTests.cs @@ -23,6 +23,7 @@ namespace Roslyn.VisualStudio.Next.UnitTests.Remote { + [UseExportProvider] public class ServiceHubServicesTests { private static RemoteWorkspace RemoteWorkspace diff --git a/src/VisualStudio/Core/Test.Next/Services/SolutionServiceTests.cs b/src/VisualStudio/Core/Test.Next/Services/SolutionServiceTests.cs index 69f33938b93c4..af386fb90dc15 100644 --- a/src/VisualStudio/Core/Test.Next/Services/SolutionServiceTests.cs +++ b/src/VisualStudio/Core/Test.Next/Services/SolutionServiceTests.cs @@ -18,6 +18,7 @@ namespace Roslyn.VisualStudio.Next.UnitTests.Remote { + [UseExportProvider] public class SolutionServiceTests { [Fact, Trait(Traits.Feature, Traits.Features.RemoteHost)] diff --git a/src/VisualStudio/Core/Test.Next/Services/VisualStudioDiagnosticAnalyzerExecutorTests.cs b/src/VisualStudio/Core/Test.Next/Services/VisualStudioDiagnosticAnalyzerExecutorTests.cs index feed3ce0ceca9..f0694beef4e07 100644 --- a/src/VisualStudio/Core/Test.Next/Services/VisualStudioDiagnosticAnalyzerExecutorTests.cs +++ b/src/VisualStudio/Core/Test.Next/Services/VisualStudioDiagnosticAnalyzerExecutorTests.cs @@ -26,6 +26,7 @@ namespace Roslyn.VisualStudio.Next.UnitTests.Remote { + [UseExportProvider] public class VisualStudioDiagnosticAnalyzerExecutorTests { [Fact, Trait(Traits.Feature, Traits.Features.RemoteHost)] @@ -234,8 +235,8 @@ await client.TryRunRemoteAsync( private TestWorkspace CreateWorkspace(string language, string code, ParseOptions options = null) { var workspace = (language == LanguageNames.CSharp) ? - TestWorkspace.CreateCSharp(code, parseOptions: options, exportProvider: TestHostServices.SharedExportProvider) : - TestWorkspace.CreateVisualBasic(code, parseOptions: options, exportProvider: TestHostServices.SharedExportProvider); + TestWorkspace.CreateCSharp(code, parseOptions: options, exportProvider: TestHostServices.CreateExportProvider()) : + TestWorkspace.CreateVisualBasic(code, parseOptions: options, exportProvider: TestHostServices.CreateExportProvider()); workspace.Options = workspace.Options.WithChangedOption(RemoteHostOptions.RemoteHostTest, true) .WithChangedOption(ServiceFeatureOnOffOptions.ClosedFileDiagnostic, LanguageNames.CSharp, true) diff --git a/src/VisualStudio/Core/Test.Next/VisualStudioTest.Next.csproj b/src/VisualStudio/Core/Test.Next/VisualStudioTest.Next.csproj index 665c180fafb6e..de753a2d413a1 100644 --- a/src/VisualStudio/Core/Test.Next/VisualStudioTest.Next.csproj +++ b/src/VisualStudio/Core/Test.Next/VisualStudioTest.Next.csproj @@ -8,7 +8,7 @@ Library Roslyn.VisualStudio.Next.UnitTests Roslyn.VisualStudio.Next.UnitTests - net461 + net46 $(RoslynDesktopRuntimeIdentifier) true UnitTest diff --git a/src/VisualStudio/Core/Test/AbstractTextViewFilterTests.vb b/src/VisualStudio/Core/Test/AbstractTextViewFilterTests.vb index 1c3977d8cd673..4f6964ea4324b 100644 --- a/src/VisualStudio/Core/Test/AbstractTextViewFilterTests.vb +++ b/src/VisualStudio/Core/Test/AbstractTextViewFilterTests.vb @@ -10,6 +10,7 @@ Imports Roslyn.Test.Utilities Imports VsTextSpan = Microsoft.VisualStudio.TextManager.Interop.TextSpan Namespace Microsoft.VisualStudio.LanguageServices.UnitTests + <[UseExportProvider]> Public Class AbstractTextViewFilterTests Public Sub MapPointsInProjectionCSharp() @@ -31,7 +32,7 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests - Using workspace = TestWorkspace.Create(workspaceXml) + Using workspace = TestWorkspace.Create(workspaceXml, exportProvider:=VisualStudioTestExportProvider.Factory.CreateExportProvider()) Dim doc = workspace.Documents.Single() Dim projected = workspace.CreateProjectionBufferDocument( - Using workspace = TestWorkspace.Create(workspaceXml) + Using workspace = TestWorkspace.Create(workspaceXml, exportProvider:=VisualStudioTestExportProvider.Factory.CreateExportProvider()) Dim doc = workspace.Documents.Single() Dim span = doc.SelectedSpans.Single() TestSpan(workspace, doc, doc.CursorPosition.Value, span.End, commandId:=CUInt(VSConstants.VSStd2KCmdID.GOTOBRACE)) @@ -98,7 +99,7 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests - Using workspace = TestWorkspace.Create(workspaceXml) + Using workspace = TestWorkspace.Create(workspaceXml, exportProvider:=VisualStudioTestExportProvider.Factory.CreateExportProvider()) Dim doc = workspace.Documents.Single() Dim span = doc.SelectedSpans.Single() TestSpan(workspace, doc, span.Start, span.End, commandId:=CUInt(VSConstants.VSStd2KCmdID.GOTOBRACE)) @@ -130,7 +131,7 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests - Using workspace = TestWorkspace.Create(workspaceXml) + Using workspace = TestWorkspace.Create(workspaceXml, exportProvider:=VisualStudioTestExportProvider.Factory.CreateExportProvider()) Dim doc = workspace.Documents.Single() Dim span = doc.SelectedSpans.Single() TestSpan(workspace, doc, caretPosition:=span.Start, startPosition:=span.Start, endPosition:=span.End, commandId:=CUInt(VSConstants.VSStd2KCmdID.GOTOBRACE_EXT)) @@ -160,7 +161,7 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests - Using workspace = TestWorkspace.Create(workspaceXml) + Using workspace = TestWorkspace.Create(workspaceXml, exportProvider:=VisualStudioTestExportProvider.Factory.CreateExportProvider()) Dim doc = workspace.Documents.Single() Dim span = doc.SelectedSpans.Single() @@ -195,7 +196,7 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests - Using workspace = TestWorkspace.Create(workspaceXml) + Using workspace = TestWorkspace.Create(workspaceXml, exportProvider:=VisualStudioTestExportProvider.Factory.CreateExportProvider()) Dim doc = workspace.Documents.Single() Dim span = doc.SelectedSpans.Single() TestSpan(workspace, doc, span.Start, span.End, commandId:=CUInt(VSConstants.VSStd2KCmdID.GOTOBRACE)) @@ -226,7 +227,7 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests - Using workspace = TestWorkspace.Create(workspaceXml) + Using workspace = TestWorkspace.Create(workspaceXml, exportProvider:=VisualStudioTestExportProvider.Factory.CreateExportProvider()) Dim doc = workspace.Documents.Single() Dim span = doc.SelectedSpans.Single() @@ -241,7 +242,7 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests End Sub Private Shared Sub TestSpan(workspace As TestWorkspace, document As TestHostDocument, startPosition As Integer, endPosition As Integer, Optional commandId As UInteger = Nothing) - Dim braceMatcher = VisualStudioTestExportProvider.ExportProvider.GetExportedValue(Of IBraceMatchingService)() + Dim braceMatcher = workspace.ExportProvider.GetExportedValue(Of IBraceMatchingService)() Dim initialLine = document.InitialTextSnapshot.GetLineFromPosition(startPosition) Dim initialLineNumber = initialLine.LineNumber Dim initialIndex = startPosition - initialLine.Start.Position @@ -263,7 +264,7 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests End Sub Private Shared Sub TestSpan(workspace As TestWorkspace, document As TestHostDocument, caretPosition As Integer, startPosition As Integer, endPosition As Integer, Optional commandId As UInteger = Nothing) - Dim braceMatcher = VisualStudioTestExportProvider.ExportProvider.GetExportedValue(Of IBraceMatchingService)() + Dim braceMatcher = workspace.ExportProvider.GetExportedValue(Of IBraceMatchingService)() Dim initialLine = document.InitialTextSnapshot.GetLineFromPosition(caretPosition) Dim initialLineNumber = initialLine.LineNumber Dim initialIndex = caretPosition - initialLine.Start.Position diff --git a/src/VisualStudio/Core/Test/AnalyzerSupport/AnalyzerDependencyCheckerTests.vb b/src/VisualStudio/Core/Test/AnalyzerSupport/AnalyzerDependencyCheckerTests.vb index e9b92bd1f12c6..033f2091fec2f 100644 --- a/src/VisualStudio/Core/Test/AnalyzerSupport/AnalyzerDependencyCheckerTests.vb +++ b/src/VisualStudio/Core/Test/AnalyzerSupport/AnalyzerDependencyCheckerTests.vb @@ -1,6 +1,7 @@ ' 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 System.Collections.Immutable +Imports System.FormattableString Imports System.IO Imports System.Text Imports Microsoft.CodeAnalysis @@ -9,9 +10,8 @@ Imports Microsoft.VisualStudio.LanguageServices.Implementation Imports Microsoft.Win32 Imports Roslyn.Test.Utilities -Imports System.FormattableString - Namespace Microsoft.VisualStudio.LanguageServices.UnitTests + <[UseExportProvider]> Public Class AnalyzerDependencyCheckerTests Inherits TestBase diff --git a/src/VisualStudio/Core/Test/CallHierarchy/CallHierarchyTests.vb b/src/VisualStudio/Core/Test/CallHierarchy/CallHierarchyTests.vb index 67c8df724c676..aadcddd3adfdd 100644 --- a/src/VisualStudio/Core/Test/CallHierarchy/CallHierarchyTests.vb +++ b/src/VisualStudio/Core/Test/CallHierarchy/CallHierarchyTests.vb @@ -7,6 +7,7 @@ Imports Microsoft.VisualStudio.Language.CallHierarchy Imports Roslyn.Test.Utilities Namespace Microsoft.CodeAnalysis.Editor.UnitTests.CallHierarchy + <[UseExportProvider]> Public Class CallHierarchyTests Public Sub TestScopes() diff --git a/src/VisualStudio/Core/Test/ChangeSignature/ChangeSignatureViewModelTests.vb b/src/VisualStudio/Core/Test/ChangeSignature/ChangeSignatureViewModelTests.vb index c9911dd1ae6d1..72a059ac86116 100644 --- a/src/VisualStudio/Core/Test/ChangeSignature/ChangeSignatureViewModelTests.vb +++ b/src/VisualStudio/Core/Test/ChangeSignature/ChangeSignatureViewModelTests.vb @@ -17,6 +17,7 @@ Imports Roslyn.Test.Utilities Imports Roslyn.Utilities Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.ChangeSignature + <[UseExportProvider]> Public Class ReorderParametersViewModelTests diff --git a/src/VisualStudio/Core/Test/ClassView/SyncClassViewTests.vb b/src/VisualStudio/Core/Test/ClassView/SyncClassViewTests.vb index 95713dba04c8f..14f4be34aab5d 100644 --- a/src/VisualStudio/Core/Test/ClassView/SyncClassViewTests.vb +++ b/src/VisualStudio/Core/Test/ClassView/SyncClassViewTests.vb @@ -8,6 +8,7 @@ Imports Microsoft.VisualStudio.Text.Editor.Commanding.Commands Imports Roslyn.Test.Utilities Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.ClassView + <[UseExportProvider]> Public Class SyncClassViewTests #Region "C# Tests" @@ -861,7 +862,7 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.ClassView ParamArray presentationNodes As NodeVerifier() ) - Using workspace = TestWorkspace.Create(workspaceDefinition, exportProvider:=VisualStudioTestExportProvider.ExportProvider) + Using workspace = TestWorkspace.Create(workspaceDefinition, exportProvider:=VisualStudioTestExportProvider.Factory.CreateExportProvider()) Dim hostDocument = workspace.DocumentWithCursor Assert.True(hostDocument IsNot Nothing, "Test defined without cursor position") diff --git a/src/VisualStudio/Core/Test/CodeModel/AbstractCodeModelObjectTests.vb b/src/VisualStudio/Core/Test/CodeModel/AbstractCodeModelObjectTests.vb index a6415edbca39c..4653eec071ce4 100644 --- a/src/VisualStudio/Core/Test/CodeModel/AbstractCodeModelObjectTests.vb +++ b/src/VisualStudio/Core/Test/CodeModel/AbstractCodeModelObjectTests.vb @@ -2,8 +2,10 @@ Imports System.Threading.Tasks Imports Microsoft.CodeAnalysis.Options +Imports Microsoft.CodeAnalysis.Test.Utilities Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.CodeModel + <[UseExportProvider]> Partial Public MustInherit Class AbstractCodeModelObjectTests(Of TCodeModelObject As Class) Protected MustOverride ReadOnly Property LanguageName As String diff --git a/src/VisualStudio/Core/Test/CodeModel/AbstractEventCollectorTests.vb b/src/VisualStudio/Core/Test/CodeModel/AbstractEventCollectorTests.vb index 58a63383fac1a..a50b1bde5d389 100644 --- a/src/VisualStudio/Core/Test/CodeModel/AbstractEventCollectorTests.vb +++ b/src/VisualStudio/Core/Test/CodeModel/AbstractEventCollectorTests.vb @@ -2,10 +2,13 @@ Imports System.Threading.Tasks Imports Microsoft.CodeAnalysis +Imports Microsoft.CodeAnalysis.Editor.UnitTests Imports Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces +Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.VisualStudio.LanguageServices.Implementation.CodeModel Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.CodeModel + <[UseExportProvider]> Public MustInherit Class AbstractEventCollectorTests Protected MustOverride ReadOnly Property LanguageName As String @@ -95,7 +98,7 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.CodeModel - Using workspace = TestWorkspace.Create(definition, exportProvider:=VisualStudioTestExportProvider.ExportProvider) + Using workspace = TestWorkspace.Create(definition, exportProvider:=VisualStudioTestExportProvider.Factory.CreateExportProvider()) Dim project = workspace.CurrentSolution.Projects.First() Dim codeModelService = project.LanguageServices.GetService(Of ICodeModelService)() Assert.NotNull(codeModelService) diff --git a/src/VisualStudio/Core/Test/CodeModel/CSharp/FileCodeModelTests.vb b/src/VisualStudio/Core/Test/CodeModel/CSharp/FileCodeModelTests.vb index 2bf69e45bde3b..a4d12a3e9ab00 100644 --- a/src/VisualStudio/Core/Test/CodeModel/CSharp/FileCodeModelTests.vb +++ b/src/VisualStudio/Core/Test/CodeModel/CSharp/FileCodeModelTests.vb @@ -1010,7 +1010,7 @@ class D Using originalWorkspaceAndFileCodeModel = CreateCodeModelTestState(GetWorkspaceDefinition(oldCode)) - Using changedworkspace = TestWorkspace.Create(changedDefinition, exportProvider:=VisualStudioTestExportProvider.ExportProvider) + Using changedworkspace = TestWorkspace.Create(changedDefinition, exportProvider:=VisualStudioTestExportProvider.Factory.CreateExportProvider()) Dim originalDocument = originalWorkspaceAndFileCodeModel.Workspace.CurrentSolution.GetDocument(originalWorkspaceAndFileCodeModel.Workspace.Documents(0).Id) Dim originalTree = Await originalDocument.GetSyntaxTreeAsync() diff --git a/src/VisualStudio/Core/Test/CodeModel/CSharp/SyntaxNodeKeyTests.vb b/src/VisualStudio/Core/Test/CodeModel/CSharp/SyntaxNodeKeyTests.vb index ade527d600367..5491600d17abd 100644 --- a/src/VisualStudio/Core/Test/CodeModel/CSharp/SyntaxNodeKeyTests.vb +++ b/src/VisualStudio/Core/Test/CodeModel/CSharp/SyntaxNodeKeyTests.vb @@ -8,6 +8,7 @@ Imports Microsoft.VisualStudio.LanguageServices.Implementation.CodeModel Imports Roslyn.Test.Utilities Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.CodeModel.CSharp + <[UseExportProvider]> Public Class SyntaxNodeKeyTests @@ -224,7 +225,7 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.CodeModel.CSharp End Function Private Async Function TestAsync(definition As XElement, expectedName As String, expectedOrdinal As Integer) As Task - Using workspace = TestWorkspace.Create(definition, exportProvider:=VisualStudioTestExportProvider.ExportProvider) + Using workspace = TestWorkspace.Create(definition, exportProvider:=VisualStudioTestExportProvider.Factory.CreateExportProvider()) Dim project = workspace.CurrentSolution.Projects.First() Dim codeModelService = project.LanguageServices.GetService(Of ICodeModelService)() Assert.NotNull(codeModelService) diff --git a/src/VisualStudio/Core/Test/CodeModel/MethodXML/MethodXMLTests.vb b/src/VisualStudio/Core/Test/CodeModel/MethodXML/MethodXMLTests.vb index eaf0e2e45021d..731f37ba91b69 100644 --- a/src/VisualStudio/Core/Test/CodeModel/MethodXML/MethodXMLTests.vb +++ b/src/VisualStudio/Core/Test/CodeModel/MethodXML/MethodXMLTests.vb @@ -1,9 +1,10 @@ ' 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 System.Threading.Tasks +Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.VisualStudio.LanguageServices.UnitTests.CodeModel Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.CodeModel.MethodXML + <[UseExportProvider]> Partial Public Class MethodXMLTests Private Sub Test(definition As XElement, expected As XElement) diff --git a/src/VisualStudio/Core/Test/CodeModel/VisualBasic/FileCodeModelTests.vb b/src/VisualStudio/Core/Test/CodeModel/VisualBasic/FileCodeModelTests.vb index 1ece98fe3d18d..9fc37773ab774 100644 --- a/src/VisualStudio/Core/Test/CodeModel/VisualBasic/FileCodeModelTests.vb +++ b/src/VisualStudio/Core/Test/CodeModel/VisualBasic/FileCodeModelTests.vb @@ -1009,7 +1009,7 @@ End Class Using originalWorkspaceAndFileCodeModel = CreateCodeModelTestState(GetWorkspaceDefinition(oldCode)) - Using changedworkspace = TestWorkspace.Create(changedDefinition, exportProvider:=VisualStudioTestExportProvider.ExportProvider) + Using changedworkspace = TestWorkspace.Create(changedDefinition, exportProvider:=VisualStudioTestExportProvider.Factory.CreateExportProvider()) Dim originalDocument = originalWorkspaceAndFileCodeModel.Workspace.CurrentSolution.GetDocument(originalWorkspaceAndFileCodeModel.Workspace.Documents(0).Id) Dim originalTree = Await originalDocument.GetSyntaxTreeAsync() diff --git a/src/VisualStudio/Core/Test/Completion/CSharpCompletionSnippetNoteTests.vb b/src/VisualStudio/Core/Test/Completion/CSharpCompletionSnippetNoteTests.vb index 0eea0121098fd..a7c010b009aac 100644 --- a/src/VisualStudio/Core/Test/Completion/CSharpCompletionSnippetNoteTests.vb +++ b/src/VisualStudio/Core/Test/Completion/CSharpCompletionSnippetNoteTests.vb @@ -10,6 +10,7 @@ Imports Microsoft.CodeAnalysis.Test.Utilities Imports Roslyn.Test.Utilities Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Completion + <[UseExportProvider]> Public Class CSharpCompletionSnippetNoteTests Private _markup As XElement = Public Class VisualBasicCompletionSnippetNoteTests Private _markup As XElement = Public Class CSharpDebuggerIntellisenseTests diff --git a/src/VisualStudio/Core/Test/DebuggerIntelliSense/TestState.vb b/src/VisualStudio/Core/Test/DebuggerIntelliSense/TestState.vb index 14b8278d45ea2..4c885744366db 100644 --- a/src/VisualStudio/Core/Test/DebuggerIntelliSense/TestState.vb +++ b/src/VisualStudio/Core/Test/DebuggerIntelliSense/TestState.vb @@ -13,6 +13,7 @@ Imports Microsoft.CodeAnalysis.Host.Mef Imports Microsoft.CodeAnalysis.Shared.Extensions Imports Microsoft.CodeAnalysis.Shared.TestHooks Imports Microsoft.CodeAnalysis.SignatureHelp +Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.Text.Shared.Extensions Imports Microsoft.VisualStudio.Commanding Imports Microsoft.VisualStudio.LanguageServices.CSharp.LanguageService @@ -50,7 +51,7 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.DebuggerIntelliSense MyBase.New( workspaceElement, - exportProvider:=MinimalTestExportProvider.CreateExportProvider(VisualStudioTestExportProvider.PartCatalog), + exportProvider:=VisualStudioTestExportProvider.Factory.CreateExportProvider(), workspaceKind:=WorkspaceKind.Debugger) Dim languageServices = Me.Workspace.CurrentSolution.Projects.First().LanguageServices diff --git a/src/VisualStudio/Core/Test/DebuggerIntelliSense/VisualBasicDebuggerIntellisenseTests.vb b/src/VisualStudio/Core/Test/DebuggerIntelliSense/VisualBasicDebuggerIntellisenseTests.vb index 2535e3c5aa5ad..10334be32404f 100644 --- a/src/VisualStudio/Core/Test/DebuggerIntelliSense/VisualBasicDebuggerIntellisenseTests.vb +++ b/src/VisualStudio/Core/Test/DebuggerIntelliSense/VisualBasicDebuggerIntellisenseTests.vb @@ -5,6 +5,7 @@ Imports Microsoft.CodeAnalysis.Test.Utilities Imports Roslyn.Test.Utilities Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.DebuggerIntelliSense + <[UseExportProvider]> Public Class VisualBasicDebuggerIntellisenseTests Public Async Function QueryVariables() As Task diff --git a/src/VisualStudio/Core/Test/Debugging/DataTipInfoGetterTests.vb b/src/VisualStudio/Core/Test/Debugging/DataTipInfoGetterTests.vb index e45fa39eca707..2e5b5b60b277f 100644 --- a/src/VisualStudio/Core/Test/Debugging/DataTipInfoGetterTests.vb +++ b/src/VisualStudio/Core/Test/Debugging/DataTipInfoGetterTests.vb @@ -13,6 +13,7 @@ Imports Roslyn.Utilities Namespace Microsoft.VisualStudio.LanguageServices.VisualBasic.UnitTests.Debugging + <[UseExportProvider]> Public Class DataTipInfoGetterTests Private Async Function TestNoDataTipAsync(input As XElement) As Task diff --git a/src/VisualStudio/Core/Test/Debugging/LocationInfoGetterTests.vb b/src/VisualStudio/Core/Test/Debugging/LocationInfoGetterTests.vb index 80527da9136c9..54500e96517d0 100644 --- a/src/VisualStudio/Core/Test/Debugging/LocationInfoGetterTests.vb +++ b/src/VisualStudio/Core/Test/Debugging/LocationInfoGetterTests.vb @@ -12,6 +12,7 @@ Imports Roslyn.Test.Utilities Namespace Microsoft.VisualStudio.LanguageServices.VisualBasic.UnitTests.Debugging + <[UseExportProvider]> Public Class LocationInfoGetterTests Private Async Function TestAsync(text As String, expectedName As String, expectedLineOffset As Integer, Optional parseOptions As VisualBasicParseOptions = Nothing, Optional rootNamespace As String = Nothing) As Tasks.Task diff --git a/src/VisualStudio/Core/Test/Debugging/NameResolverTests.vb b/src/VisualStudio/Core/Test/Debugging/NameResolverTests.vb index 1ac3b50affdf8..c9c666097b30e 100644 --- a/src/VisualStudio/Core/Test/Debugging/NameResolverTests.vb +++ b/src/VisualStudio/Core/Test/Debugging/NameResolverTests.vb @@ -10,6 +10,7 @@ Imports Microsoft.VisualStudio.LanguageServices.VisualBasic.Debugging Namespace Microsoft.VisualStudio.LanguageServices.VisualBasic.UnitTests.Debugging + <[UseExportProvider]> Public Class NameResolverTests Private Function TestAsync(text As String, searchText As String, ParamArray expectedNames() As String) As Tasks.Task diff --git a/src/VisualStudio/Core/Test/Debugging/ProximityExpressionsGetterTests.Statements.vb b/src/VisualStudio/Core/Test/Debugging/ProximityExpressionsGetterTests.Statements.vb index ac3093ae3dd6a..f540d78606507 100644 --- a/src/VisualStudio/Core/Test/Debugging/ProximityExpressionsGetterTests.Statements.vb +++ b/src/VisualStudio/Core/Test/Debugging/ProximityExpressionsGetterTests.Statements.vb @@ -6,6 +6,7 @@ Imports Microsoft.VisualStudio.LanguageServices.VisualBasic.Debugging Imports Roslyn.Test.Utilities Namespace Microsoft.VisualStudio.LanguageServices.VisualBasic.UnitTests.Debugging + <[UseExportProvider]> Partial Public Class ProximityExpressionsGetterTests Public Sub TestAtStartOfStatement_0() diff --git a/src/VisualStudio/Core/Test/Debugging/VisualBasicBreakpointResolutionServiceTests.vb b/src/VisualStudio/Core/Test/Debugging/VisualBasicBreakpointResolutionServiceTests.vb index 7083df080c44e..de102c8f99429 100644 --- a/src/VisualStudio/Core/Test/Debugging/VisualBasicBreakpointResolutionServiceTests.vb +++ b/src/VisualStudio/Core/Test/Debugging/VisualBasicBreakpointResolutionServiceTests.vb @@ -2,17 +2,18 @@ Imports System.Threading Imports System.Threading.Tasks -Imports System.Xml.Linq Imports Microsoft.CodeAnalysis Imports Microsoft.CodeAnalysis.Editor.Implementation.Debugging Imports Microsoft.CodeAnalysis.Editor.UnitTests.Extensions Imports Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces +Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.Text Imports Microsoft.VisualStudio.LanguageServices.VisualBasic.Debugging Imports Roslyn.Test.Utilities Imports Roslyn.Utilities Namespace Microsoft.VisualStudio.LanguageServices.VisualBasic.UnitTests.Debugging + <[UseExportProvider]> Public Class VisualBasicBreakpointResolutionServiceTests Public Async Function TestSpanWithLengthAsync(markup As XElement, length As Integer) As Task diff --git a/src/VisualStudio/Core/Test/Diagnostics/DefaultDiagnosticUpdateSourceTests.vb b/src/VisualStudio/Core/Test/Diagnostics/DefaultDiagnosticUpdateSourceTests.vb index faf6b3ae46e41..6189b03101b9b 100644 --- a/src/VisualStudio/Core/Test/Diagnostics/DefaultDiagnosticUpdateSourceTests.vb +++ b/src/VisualStudio/Core/Test/Diagnostics/DefaultDiagnosticUpdateSourceTests.vb @@ -9,16 +9,16 @@ Imports Microsoft.CodeAnalysis.Editor Imports Microsoft.CodeAnalysis.Editor.Implementation.Diagnostics Imports Microsoft.CodeAnalysis.Editor.UnitTests.Diagnostics Imports Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces -Imports Microsoft.CodeAnalysis.Options Imports Microsoft.CodeAnalysis.Shared.TestHooks Imports Microsoft.CodeAnalysis.SolutionCrawler +Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.Text.Shared.Extensions -Imports Microsoft.VisualStudio.LanguageServices.Implementation.Diagnostics Imports Microsoft.VisualStudio.Text.Tagging Imports Roslyn.Test.Utilities Imports Roslyn.Utilities Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Diagnostics + <[UseExportProvider]> Public Class DefaultDiagnosticUpdateSourceTests Public Async Function TestMiscSquiggles() As Task @@ -26,7 +26,7 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Diagnostics class 123 { } Using workspace = TestWorkspace.CreateCSharp(code.Value) - Dim listenerProvider = New AsynchronousOperationListenerProvider() + Dim listenerProvider = workspace.ExportProvider.GetExportedValue(Of IAsynchronousOperationListenerProvider) Dim diagnosticService = New DiagnosticService(listenerProvider) Dim miscService = New DefaultDiagnosticAnalyzerService(diagnosticService) @@ -69,7 +69,7 @@ class A Using workspace = TestWorkspace.CreateCSharp(code.Value) - Dim listenerProvider = New AsynchronousOperationListenerProvider() + Dim listenerProvider = workspace.ExportProvider.GetExportedValue(Of IAsynchronousOperationListenerProvider) Dim diagnosticService = New DiagnosticService(listenerProvider) Dim miscService = New DefaultDiagnosticAnalyzerService(diagnosticService) @@ -104,7 +104,7 @@ class A Using workspace = TestWorkspace.CreateCSharp(code.Value) - Dim listenerProvider = New AsynchronousOperationListenerProvider() + Dim listenerProvider = workspace.ExportProvider.GetExportedValue(Of IAsynchronousOperationListenerProvider) Dim diagnosticService = New DiagnosticService(listenerProvider) Dim miscService = New DefaultDiagnosticAnalyzerService(diagnosticService) @@ -138,7 +138,7 @@ class A Using workspace = TestWorkspace.CreateCSharp(code.Value) - Dim listenerProvider = New AsynchronousOperationListenerProvider() + Dim listenerProvider = workspace.ExportProvider.GetExportedValue(Of IAsynchronousOperationListenerProvider) Dim diagnosticService = New DiagnosticService(listenerProvider) Dim miscService = New DefaultDiagnosticAnalyzerService(diagnosticService) @@ -172,7 +172,7 @@ class A Using workspace = TestWorkspace.CreateCSharp(code.Value) - Dim listenerProvider = New AsynchronousOperationListenerProvider() + Dim listenerProvider = workspace.ExportProvider.GetExportedValue(Of IAsynchronousOperationListenerProvider) Dim diagnosticService = New DiagnosticService(listenerProvider) Dim miscService = New DefaultDiagnosticAnalyzerService(diagnosticService) diff --git a/src/VisualStudio/Core/Test/Diagnostics/DiagnosticTableDataSourceTests.vb b/src/VisualStudio/Core/Test/Diagnostics/DiagnosticTableDataSourceTests.vb index ea70557f99962..055c5fb557847 100644 --- a/src/VisualStudio/Core/Test/Diagnostics/DiagnosticTableDataSourceTests.vb +++ b/src/VisualStudio/Core/Test/Diagnostics/DiagnosticTableDataSourceTests.vb @@ -8,12 +8,12 @@ Imports System.Windows.Controls Imports Microsoft.CodeAnalysis Imports Microsoft.CodeAnalysis.Common Imports Microsoft.CodeAnalysis.Diagnostics -Imports Microsoft.CodeAnalysis.Editor.UnitTests Imports Microsoft.CodeAnalysis.Editor.UnitTests.Diagnostics Imports Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces Imports Microsoft.CodeAnalysis.Options Imports Microsoft.CodeAnalysis.Shared.TestHooks Imports Microsoft.CodeAnalysis.SolutionCrawler +Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.Text Imports Microsoft.VisualStudio.LanguageServices.Implementation.TableDataSource Imports Microsoft.VisualStudio.LanguageServices.Implementation.TaskList @@ -23,6 +23,7 @@ Imports Roslyn.Test.Utilities Imports Roslyn.Utilities Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Diagnostics + <[UseExportProvider]> Public Class DiagnosticTableDataSourceTests Public Sub TestCreation() @@ -616,7 +617,7 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Diagnostics Using workspace = TestWorkspace.Create(markup) - Dim listenerProvider = New AsynchronousOperationListenerProvider() + Dim listenerProvider = workspace.ExportProvider.GetExportedValue(Of IAsynchronousOperationListenerProvider) Dim service = New DiagnosticService(listenerProvider) Dim tableManagerProvider = New TestTableManagerProvider() @@ -664,7 +665,7 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Diagnostics Using workspace = TestWorkspace.Create(markup) - Dim listenerProvider = New AsynchronousOperationListenerProvider() + Dim listenerProvider = workspace.ExportProvider.GetExportedValue(Of IAsynchronousOperationListenerProvider) Dim listener = listenerProvider.GetListener(FeatureAttribute.DiagnosticService) Dim service = New DiagnosticService(listenerProvider) diff --git a/src/VisualStudio/Core/Test/Diagnostics/ExternalDiagnosticUpdateSourceTests.vb b/src/VisualStudio/Core/Test/Diagnostics/ExternalDiagnosticUpdateSourceTests.vb index 486d1339b0043..ffc3e0671d3b9 100644 --- a/src/VisualStudio/Core/Test/Diagnostics/ExternalDiagnosticUpdateSourceTests.vb +++ b/src/VisualStudio/Core/Test/Diagnostics/ExternalDiagnosticUpdateSourceTests.vb @@ -8,11 +8,13 @@ Imports Microsoft.CodeAnalysis.Diagnostics Imports Microsoft.CodeAnalysis.Editor.UnitTests.Diagnostics Imports Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces Imports Microsoft.CodeAnalysis.Shared.TestHooks +Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.Text Imports Microsoft.VisualStudio.LanguageServices.Implementation.TaskList Imports Roslyn.Utilities Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Diagnostics + <[UseExportProvider]> Public Class ExternalDiagnosticUpdateSourceTests Public Sub TestExternalDiagnostics_SupportGetDiagnostics() diff --git a/src/VisualStudio/Core/Test/Diagnostics/TodoListTableDataSourceTests.vb b/src/VisualStudio/Core/Test/Diagnostics/TodoListTableDataSourceTests.vb index befca79b6add5..d47e48515d536 100644 --- a/src/VisualStudio/Core/Test/Diagnostics/TodoListTableDataSourceTests.vb +++ b/src/VisualStudio/Core/Test/Diagnostics/TodoListTableDataSourceTests.vb @@ -2,17 +2,18 @@ Imports System.Collections.Immutable Imports System.Threading -Imports System.Threading.Tasks Imports Microsoft.CodeAnalysis Imports Microsoft.CodeAnalysis.Common Imports Microsoft.CodeAnalysis.Editor Imports Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces +Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.VisualStudio.LanguageServices.Implementation.TableDataSource Imports Microsoft.VisualStudio.Shell.TableManager Imports Roslyn.Test.Utilities Imports Roslyn.Utilities Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Diagnostics + <[UseExportProvider]> Public Class TodoListTableDataSourceTests Public Sub TestCreation() diff --git a/src/VisualStudio/Core/Test/EditAndContinue/EditAndContinueWorkspaceServiceTests.vb b/src/VisualStudio/Core/Test/EditAndContinue/EditAndContinueWorkspaceServiceTests.vb index f401a2fb53ea9..293700f8b567f 100644 --- a/src/VisualStudio/Core/Test/EditAndContinue/EditAndContinueWorkspaceServiceTests.vb +++ b/src/VisualStudio/Core/Test/EditAndContinue/EditAndContinueWorkspaceServiceTests.vb @@ -4,8 +4,10 @@ Imports System.Collections.Immutable Imports Microsoft.CodeAnalysis Imports Microsoft.CodeAnalysis.Diagnostics Imports Microsoft.CodeAnalysis.EditAndContinue +Imports Microsoft.CodeAnalysis.Test.Utilities Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.EditAndContinue + <[UseExportProvider]> Public Class EditAndContinueWorkspaceServiceTests Public Sub ReadOnlyDocumentTest() diff --git a/src/VisualStudio/Core/Test/EditAndContinue/VsReadOnlyDocumentTrackerTests.vb b/src/VisualStudio/Core/Test/EditAndContinue/VsReadOnlyDocumentTrackerTests.vb index 807e5590cfbb7..0f8484c01204b 100644 --- a/src/VisualStudio/Core/Test/EditAndContinue/VsReadOnlyDocumentTrackerTests.vb +++ b/src/VisualStudio/Core/Test/EditAndContinue/VsReadOnlyDocumentTrackerTests.vb @@ -1,24 +1,22 @@ ' 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 System.Collections.Immutable -Imports System.IO -Imports System.Threading.Tasks Imports Microsoft.CodeAnalysis Imports Microsoft.CodeAnalysis.Diagnostics Imports Microsoft.CodeAnalysis.EditAndContinue Imports Microsoft.CodeAnalysis.Editor.Implementation.EditAndContinue +Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.VisualStudio.Editor -Imports Microsoft.VisualStudio.LanguageServices.Implementation.ProjectSystem Imports Microsoft.VisualStudio.OLE.Interop Imports Microsoft.VisualStudio.Text Imports Microsoft.VisualStudio.Text.Editor Imports Microsoft.VisualStudio.TextManager.Interop Imports Microsoft.VisualStudio.Utilities -Imports Moq Imports Roslyn.Test.Utilities Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.EditAndContinue + <[UseExportProvider]> Public Class VsReadOnlyDocumentTrackerTests Public Sub StandardTextDocumentTest() diff --git a/src/VisualStudio/Core/Test/ExtractInterface/ExtractInterfaceViewModelTests.vb b/src/VisualStudio/Core/Test/ExtractInterface/ExtractInterfaceViewModelTests.vb index 7001d45e2f4ac..0941a4c5dbec9 100644 --- a/src/VisualStudio/Core/Test/ExtractInterface/ExtractInterfaceViewModelTests.vb +++ b/src/VisualStudio/Core/Test/ExtractInterface/ExtractInterfaceViewModelTests.vb @@ -13,6 +13,7 @@ Imports Microsoft.VisualStudio.LanguageServices.Implementation.ExtractInterface Imports Roslyn.Test.Utilities Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.ExtractInterface + <[UseExportProvider]> Public Class ExtractInterfaceViewModelTests Public Async Function TestExtractInterface_InterfaceNameIsSameAsPassedIn() As Task diff --git a/src/VisualStudio/Core/Test/GenerateType/GenerateTypeViewModelTests.vb b/src/VisualStudio/Core/Test/GenerateType/GenerateTypeViewModelTests.vb index fb1121b08ff5a..6dc46341e68ca 100644 --- a/src/VisualStudio/Core/Test/GenerateType/GenerateTypeViewModelTests.vb +++ b/src/VisualStudio/Core/Test/GenerateType/GenerateTypeViewModelTests.vb @@ -16,6 +16,7 @@ Imports Microsoft.VisualStudio.LanguageServices.Implementation.GenerateType Imports Roslyn.Test.Utilities Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.GenerateType + <[UseExportProvider]> Public Class GenerateTypeViewModelTests Private Shared s_assembly1_Name As String = "Assembly1" Private Shared s_test1_Name As String = "Test1" diff --git a/src/VisualStudio/Core/Test/GoToDefinition/GoToDefinitionApiTests.vb b/src/VisualStudio/Core/Test/GoToDefinition/GoToDefinitionApiTests.vb index 37ffb7f5939e6..ac5a533cbedc9 100644 --- a/src/VisualStudio/Core/Test/GoToDefinition/GoToDefinitionApiTests.vb +++ b/src/VisualStudio/Core/Test/GoToDefinition/GoToDefinitionApiTests.vb @@ -10,10 +10,11 @@ Imports Microsoft.CodeAnalysis.Test.Utilities Imports Roslyn.Test.Utilities Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.GoToDefinition + <[UseExportProvider]> Public Class GoToDefinitionApiTests Private Async Function TestAsync(workspaceDefinition As XElement, expectSuccess As Boolean) As Tasks.Task - Using workspace = TestWorkspace.Create(workspaceDefinition, exportProvider:=GoToTestHelpers.ExportProvider) + Using workspace = TestWorkspace.Create(workspaceDefinition, exportProvider:=GoToTestHelpers.ExportProviderFactory.CreateExportProvider()) Dim solution = workspace.CurrentSolution Dim cursorDocument = workspace.Documents.First(Function(d) d.CursorPosition.HasValue) Dim cursorPosition = cursorDocument.CursorPosition.Value @@ -35,7 +36,7 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.GoToDefinition Assert.NotNull(symbolInfo.Symbol) - Dim presenter = New MockStreamingFindUsagesPresenter(Sub () Exit sub) + Dim presenter = New MockStreamingFindUsagesPresenter(Sub() Exit Sub) WpfTestCase.RequireWpfFact($"{NameOf(GoToDefinitionHelpers)}.{NameOf(GoToDefinitionHelpers.TryGoToDefinition)} assumes it's on the UI thread with a WaitAndGetResult call") Dim success = GoToDefinitionHelpers.TryGoToDefinition( diff --git a/src/VisualStudio/Core/Test/Help/HelpTests.vb b/src/VisualStudio/Core/Test/Help/HelpTests.vb index 4d2c0e2ec0c2d..506d7985d16b6 100644 --- a/src/VisualStudio/Core/Test/Help/HelpTests.vb +++ b/src/VisualStudio/Core/Test/Help/HelpTests.vb @@ -9,6 +9,7 @@ Imports Roslyn.Test.Utilities Imports Roslyn.Utilities Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Help + <[UseExportProvider]> Public Class HelpTests Public Async Function TestAsync(markup As String, expected As String) As Tasks.Task Using workspace = TestWorkspace.CreateVisualBasic(markup) diff --git a/src/VisualStudio/Core/Test/LanguageBlockTests.vb b/src/VisualStudio/Core/Test/LanguageBlockTests.vb index 682bf8986efeb..615ef1fde0663 100644 --- a/src/VisualStudio/Core/Test/LanguageBlockTests.vb +++ b/src/VisualStudio/Core/Test/LanguageBlockTests.vb @@ -8,6 +8,7 @@ Imports Microsoft.VisualStudio.LanguageServices.Implementation.LanguageService Imports Roslyn.Test.Utilities Namespace Tests + <[UseExportProvider]> Public Class LanguageBlockTests Public Sub TestGetCurrentBlock_NotInImports_VB() diff --git a/src/VisualStudio/Core/Test/ObjectBrowser/AbstractObjectBrowserTests.vb b/src/VisualStudio/Core/Test/ObjectBrowser/AbstractObjectBrowserTests.vb index d7bf4eb39e5a4..caae0e407c327 100644 --- a/src/VisualStudio/Core/Test/ObjectBrowser/AbstractObjectBrowserTests.vb +++ b/src/VisualStudio/Core/Test/ObjectBrowser/AbstractObjectBrowserTests.vb @@ -1,12 +1,14 @@ ' 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 System.Runtime.ExceptionServices -Imports System.Threading.Tasks +Imports Microsoft.CodeAnalysis.Editor.UnitTests Imports Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces +Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.VisualStudio.LanguageServices.Implementation.Library.ObjectBrowser Imports Microsoft.VisualStudio.LanguageServices.UnitTests.ObjectBrowser.Mocks Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.ObjectBrowser + <[UseExportProvider]> Public MustInherit Class AbstractObjectBrowserTests Protected MustOverride ReadOnly Property LanguageName As String @@ -21,7 +23,7 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.ObjectBrowser Friend Function CreateLibraryManager(definition As XElement) As TestState - Dim workspace = TestWorkspace.Create(definition, exportProvider:=VisualStudioTestExportProvider.ExportProvider) + Dim workspace = TestWorkspace.Create(definition, exportProvider:=VisualStudioTestExportProvider.Factory.CreateExportProvider()) Dim result As TestState = Nothing Try diff --git a/src/VisualStudio/Core/Test/Preview/PreviewChangesTests.vb b/src/VisualStudio/Core/Test/Preview/PreviewChangesTests.vb index 3584bb861f6dc..eed316e8d6e31 100644 --- a/src/VisualStudio/Core/Test/Preview/PreviewChangesTests.vb +++ b/src/VisualStudio/Core/Test/Preview/PreviewChangesTests.vb @@ -1,9 +1,9 @@ ' 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 System.Threading.Tasks Imports Microsoft.CodeAnalysis Imports Microsoft.CodeAnalysis.Editor.UnitTests Imports Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces +Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.Text Imports Microsoft.VisualStudio.Composition Imports Microsoft.VisualStudio.LanguageServices.Implementation.Preview @@ -11,9 +11,10 @@ Imports Microsoft.VisualStudio.Text.Editor Imports Roslyn.Test.Utilities Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Preview + <[UseExportProvider]> Public Class PreviewChangesTests - Private _exportProvider As ExportProvider = MinimalTestExportProvider.CreateExportProvider( + Private _exportProviderFactory As IExportProviderFactory = ExportProviderCache.GetOrCreateExportProviderFactory( TestExportProvider.MinimumCatalogWithCSharpAndVisualBasic.WithPart(GetType(StubVsEditorAdaptersFactoryService))) @@ -25,7 +26,7 @@ Class C { $$ } -}.Value, exportProvider:=_exportProvider) +}.Value, exportProvider:=_exportProviderFactory.CreateExportProvider()) Dim expectedItems = New List(Of Tuple(Of String, Integer)) From { Tuple.Create("topLevelItemName", 0), @@ -74,7 +75,7 @@ Class C - Using workspace = TestWorkspace.Create(workspaceXml, exportProvider:=_exportProvider) + Using workspace = TestWorkspace.Create(workspaceXml, exportProvider:=_exportProviderFactory.CreateExportProvider()) Dim expectedItems = New List(Of Tuple(Of String, Integer)) From { Tuple.Create("topLevelItemName", 0), @@ -125,7 +126,7 @@ Class C { $$ } -}.Value, exportProvider:=_exportProvider) +}.Value, exportProvider:=_exportProviderFactory.CreateExportProvider()) Dim expectedItems = New List(Of String) From {"topLevelItemName", "*test1.cs", "**insertion!"} Dim documentId = workspace.Documents.First().Id @@ -181,7 +182,7 @@ Class C - Using workspace = TestWorkspace.Create(workspaceXml, exportProvider:=_exportProvider) + Using workspace = TestWorkspace.Create(workspaceXml, exportProvider:=_exportProviderFactory.CreateExportProvider()) Dim docId = workspace.Documents.First().Id Dim document = workspace.CurrentSolution.GetDocument(docId) @@ -264,7 +265,7 @@ End Class - Using workspace = TestWorkspace.Create(workspaceXml, , exportProvider:=_exportProvider) + Using workspace = TestWorkspace.Create(workspaceXml, , exportProvider:=_exportProviderFactory.CreateExportProvider()) Dim documentId1 = workspace.Documents.Where(Function(d) d.Project.Name = "VBProj1").Single().Id Dim document1 = workspace.CurrentSolution.GetDocument(documentId1) diff --git a/src/VisualStudio/Core/Test/Progression/CSharpSymbolLabelTests.vb b/src/VisualStudio/Core/Test/Progression/CSharpSymbolLabelTests.vb index 7773e1c94b831..468989cb2cd4c 100644 --- a/src/VisualStudio/Core/Test/Progression/CSharpSymbolLabelTests.vb +++ b/src/VisualStudio/Core/Test/Progression/CSharpSymbolLabelTests.vb @@ -6,6 +6,7 @@ Imports Microsoft.VisualStudio.GraphModel Imports Roslyn.Test.Utilities Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Progression + <[UseExportProvider]> Public Class CSharpSymbolLabelTests Public Async Function TestNamedType() As Task diff --git a/src/VisualStudio/Core/Test/Progression/CallsGraphQueryTests.vb b/src/VisualStudio/Core/Test/Progression/CallsGraphQueryTests.vb index 5438a140862db..7dac77a289ceb 100644 --- a/src/VisualStudio/Core/Test/Progression/CallsGraphQueryTests.vb +++ b/src/VisualStudio/Core/Test/Progression/CallsGraphQueryTests.vb @@ -6,6 +6,7 @@ Imports Microsoft.VisualStudio.GraphModel Imports Microsoft.VisualStudio.LanguageServices.Implementation.Progression Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Progression + <[UseExportProvider]> Public Class CallsGraphQueryTests Public Async Function CallsSimpleTests() As Task diff --git a/src/VisualStudio/Core/Test/Progression/ContainsChildrenGraphQueryTests.vb b/src/VisualStudio/Core/Test/Progression/ContainsChildrenGraphQueryTests.vb index 2cd16a0d11934..c7c829f1771c5 100644 --- a/src/VisualStudio/Core/Test/Progression/ContainsChildrenGraphQueryTests.vb +++ b/src/VisualStudio/Core/Test/Progression/ContainsChildrenGraphQueryTests.vb @@ -8,6 +8,7 @@ Imports Microsoft.VisualStudio.LanguageServices.Implementation.Progression Imports Roslyn.Test.Utilities Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Progression + <[UseExportProvider]> Public Class ContainsChildrenGraphQueryTests Public Async Function ContainsChildrenForDocument() As Task diff --git a/src/VisualStudio/Core/Test/Progression/ContainsGraphQueryTests.vb b/src/VisualStudio/Core/Test/Progression/ContainsGraphQueryTests.vb index a9a54852ef083..68af8c09db557 100644 --- a/src/VisualStudio/Core/Test/Progression/ContainsGraphQueryTests.vb +++ b/src/VisualStudio/Core/Test/Progression/ContainsGraphQueryTests.vb @@ -7,6 +7,7 @@ Imports Microsoft.VisualStudio.LanguageServices.Implementation.Progression Imports Roslyn.Test.Utilities Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Progression + <[UseExportProvider]> Public Class ContainsGraphQueryTests Public Async Function TypesContainedInCSharpDocument() As Task diff --git a/src/VisualStudio/Core/Test/Progression/GraphNodeCreationTests.vb b/src/VisualStudio/Core/Test/Progression/GraphNodeCreationTests.vb index 1e979f68993c4..d46d606fe7359 100644 --- a/src/VisualStudio/Core/Test/Progression/GraphNodeCreationTests.vb +++ b/src/VisualStudio/Core/Test/Progression/GraphNodeCreationTests.vb @@ -9,6 +9,7 @@ Imports Microsoft.VisualStudio.LanguageServices.Implementation.Progression Imports Microsoft.VisualStudio.LanguageServices.Progression Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Progression + <[UseExportProvider]> Public Class GraphNodeCreationTests Private Async Function AssertCreatedNodeIsAsync(code As String, expectedId As String, xml As XElement, Optional language As String = "C#") As Task Using testState = ProgressionTestState.Create( diff --git a/src/VisualStudio/Core/Test/Progression/GraphNodeIdTests.vb b/src/VisualStudio/Core/Test/Progression/GraphNodeIdTests.vb index 7b2139362b3dd..5abafa92d56a3 100644 --- a/src/VisualStudio/Core/Test/Progression/GraphNodeIdTests.vb +++ b/src/VisualStudio/Core/Test/Progression/GraphNodeIdTests.vb @@ -7,6 +7,7 @@ Imports Microsoft.VisualStudio.GraphModel Imports Roslyn.Test.Utilities Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Progression + <[UseExportProvider]> Public Class GraphNodeIdTests Private Async Function AssertMarkedNodeIdIsAsync(code As String, expectedId As String, Optional language As String = "C#", Optional symbolTransform As Func(Of ISymbol, ISymbol) = Nothing) As Task Using testState = ProgressionTestState.Create( diff --git a/src/VisualStudio/Core/Test/Progression/ImplementedByGraphQueryTests.vb b/src/VisualStudio/Core/Test/Progression/ImplementedByGraphQueryTests.vb index de8049e978a3a..04551f20694b8 100644 --- a/src/VisualStudio/Core/Test/Progression/ImplementedByGraphQueryTests.vb +++ b/src/VisualStudio/Core/Test/Progression/ImplementedByGraphQueryTests.vb @@ -7,6 +7,7 @@ Imports Microsoft.VisualStudio.LanguageServices.Implementation.Progression Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Progression + <[UseExportProvider]> Public Class ImplementedByGraphQueryTests Public Async Function TestImplementedBy1() As Task diff --git a/src/VisualStudio/Core/Test/Progression/ImplementsGraphQueryTests.vb b/src/VisualStudio/Core/Test/Progression/ImplementsGraphQueryTests.vb index 8d9c97488d08c..41687ca7851c8 100644 --- a/src/VisualStudio/Core/Test/Progression/ImplementsGraphQueryTests.vb +++ b/src/VisualStudio/Core/Test/Progression/ImplementsGraphQueryTests.vb @@ -7,6 +7,7 @@ Imports Microsoft.VisualStudio.LanguageServices.Implementation.Progression Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Progression + <[UseExportProvider]> Public Class ImplementsGraphQueryTests Public Async Function TestClassImplementsInterface1() As Task diff --git a/src/VisualStudio/Core/Test/Progression/InheritedByGraphQueryTests.vb b/src/VisualStudio/Core/Test/Progression/InheritedByGraphQueryTests.vb index 0be718b63c6e8..4334fac652f31 100644 --- a/src/VisualStudio/Core/Test/Progression/InheritedByGraphQueryTests.vb +++ b/src/VisualStudio/Core/Test/Progression/InheritedByGraphQueryTests.vb @@ -7,6 +7,7 @@ Imports Microsoft.VisualStudio.LanguageServices.Implementation.Progression Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Progression + <[UseExportProvider]> Public Class InheritedByGraphQueryTests Public Async Function TestInheritedByClassesCSharp() As Task diff --git a/src/VisualStudio/Core/Test/Progression/InheritsFromGraphQueryTests.vb b/src/VisualStudio/Core/Test/Progression/InheritsFromGraphQueryTests.vb index e9652552be20e..6f7a6569c39fd 100644 --- a/src/VisualStudio/Core/Test/Progression/InheritsFromGraphQueryTests.vb +++ b/src/VisualStudio/Core/Test/Progression/InheritsFromGraphQueryTests.vb @@ -7,6 +7,7 @@ Imports Microsoft.VisualStudio.LanguageServices.Implementation.Progression Imports Roslyn.Test.Utilities Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Progression + <[UseExportProvider]> Public Class InheritsGraphQueryTests Public Async Function BaseTypesOfSimpleType() As Task diff --git a/src/VisualStudio/Core/Test/Progression/IsCalledByGraphQueryTests.vb b/src/VisualStudio/Core/Test/Progression/IsCalledByGraphQueryTests.vb index 9d8f7dd16a644..37ccd0805beb5 100644 --- a/src/VisualStudio/Core/Test/Progression/IsCalledByGraphQueryTests.vb +++ b/src/VisualStudio/Core/Test/Progression/IsCalledByGraphQueryTests.vb @@ -6,6 +6,7 @@ Imports Microsoft.VisualStudio.GraphModel Imports Microsoft.VisualStudio.LanguageServices.Implementation.Progression Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Progression + <[UseExportProvider]> Public Class IsCalledByGraphQueryTests Public Async Function IsCalledBySimpleTests() As Task diff --git a/src/VisualStudio/Core/Test/Progression/IsUsedByGraphQueryTests.vb b/src/VisualStudio/Core/Test/Progression/IsUsedByGraphQueryTests.vb index b4e7dda25013f..1d4218957d51f 100644 --- a/src/VisualStudio/Core/Test/Progression/IsUsedByGraphQueryTests.vb +++ b/src/VisualStudio/Core/Test/Progression/IsUsedByGraphQueryTests.vb @@ -6,6 +6,7 @@ Imports Microsoft.VisualStudio.GraphModel Imports Microsoft.VisualStudio.LanguageServices.Implementation.Progression Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Progression + <[UseExportProvider]> Public Class IsUsedByGraphQueryTests Public Async Function IsUsedByTests() As Task diff --git a/src/VisualStudio/Core/Test/Progression/OverriddenByGraphQueryTests.vb b/src/VisualStudio/Core/Test/Progression/OverriddenByGraphQueryTests.vb index cdc5bf67ff03c..96ef92ab64890 100644 --- a/src/VisualStudio/Core/Test/Progression/OverriddenByGraphQueryTests.vb +++ b/src/VisualStudio/Core/Test/Progression/OverriddenByGraphQueryTests.vb @@ -7,6 +7,7 @@ Imports Microsoft.VisualStudio.LanguageServices.Implementation.Progression Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Progression + <[UseExportProvider]> Public Class OverriddenByGraphQueryTests Public Async Function TestOverriddenByMethod1() As Task diff --git a/src/VisualStudio/Core/Test/Progression/OverridesGraphQueryTests.vb b/src/VisualStudio/Core/Test/Progression/OverridesGraphQueryTests.vb index 0f40c5256fc90..964fade79bede 100644 --- a/src/VisualStudio/Core/Test/Progression/OverridesGraphQueryTests.vb +++ b/src/VisualStudio/Core/Test/Progression/OverridesGraphQueryTests.vb @@ -7,6 +7,7 @@ Imports Microsoft.VisualStudio.LanguageServices.Implementation.Progression Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Progression + <[UseExportProvider]> Public Class OverridesGraphQueryTests Public Async Function TestOverridesMethod1() As Task diff --git a/src/VisualStudio/Core/Test/Progression/ProgressionTestHelpers.vb b/src/VisualStudio/Core/Test/Progression/ProgressionTestHelpers.vb index a005c08b7d38c..83742e7a2840b 100644 --- a/src/VisualStudio/Core/Test/Progression/ProgressionTestHelpers.vb +++ b/src/VisualStudio/Core/Test/Progression/ProgressionTestHelpers.vb @@ -2,19 +2,19 @@ Imports System.Runtime.CompilerServices Imports Microsoft.CodeAnalysis.Editor.UnitTests +Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.VisualStudio.Composition Imports Microsoft.VisualStudio.GraphModel Imports Microsoft.VisualStudio.LanguageServices.CSharp.Progression -Imports Microsoft.VisualStudio.LanguageServices.Implementation.Progression Imports Microsoft.VisualStudio.LanguageServices.VisualBasic.Progression Imports Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Progression Friend Module ProgressionTestHelpers - Public ReadOnly CompositionCatalog As ComposableCatalog = + Public ReadOnly ExportProviderFactory As IExportProviderFactory = ExportProviderCache.GetOrCreateExportProviderFactory( TestExportProvider.EntireAssemblyCatalogWithCSharpAndVisualBasic.WithParts( GetType(CSharpProgressionLanguageService), - GetType(VisualBasicProgressionLanguageService)) + GetType(VisualBasicProgressionLanguageService))) Public Function ToSimplifiedXDocument(graph As Graph) As XDocument diff --git a/src/VisualStudio/Core/Test/Progression/ProgressionTestState.vb b/src/VisualStudio/Core/Test/Progression/ProgressionTestState.vb index 4088167d07fae..e0c64a67631ba 100644 --- a/src/VisualStudio/Core/Test/Progression/ProgressionTestState.vb +++ b/src/VisualStudio/Core/Test/Progression/ProgressionTestState.vb @@ -1,6 +1,5 @@ ' 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 System.ComponentModel.Composition.Hosting Imports System.Threading Imports System.Threading.Tasks Imports Microsoft.CodeAnalysis @@ -8,8 +7,6 @@ Imports Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces Imports Microsoft.CodeAnalysis.FindSymbols Imports Microsoft.VisualStudio.GraphModel Imports Microsoft.VisualStudio.LanguageServices.Implementation.Progression -Imports Roslyn.Test.Utilities -Imports Microsoft.CodeAnalysis.Editor.UnitTests Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Progression Friend Class ProgressionTestState @@ -22,8 +19,7 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Progression End Sub Public Shared Function Create(workspaceXml As XElement) As ProgressionTestState - Dim workspace = TestWorkspace.Create(workspaceXml, -exportProvider:=MinimalTestExportProvider.CreateExportProvider(CompositionCatalog)) + Dim workspace = TestWorkspace.Create(workspaceXml, exportProvider:=ExportProviderFactory.CreateExportProvider()) Return New ProgressionTestState(workspace) End Function diff --git a/src/VisualStudio/Core/Test/Progression/SearchGraphQueryTests.vb b/src/VisualStudio/Core/Test/Progression/SearchGraphQueryTests.vb index 664e2e8e289f6..fb4736356a4f4 100644 --- a/src/VisualStudio/Core/Test/Progression/SearchGraphQueryTests.vb +++ b/src/VisualStudio/Core/Test/Progression/SearchGraphQueryTests.vb @@ -8,6 +8,7 @@ Imports Microsoft.VisualStudio.LanguageServices.Implementation.Progression Imports Roslyn.Test.Utilities Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Progression + <[UseExportProvider]> Public Class SearchGraphQueryTests Public Async Function SearchForType() As Task diff --git a/src/VisualStudio/Core/Test/Progression/VisualBasicSymbolLabelTests.vb b/src/VisualStudio/Core/Test/Progression/VisualBasicSymbolLabelTests.vb index 1baebc397f7de..60f72e71b9951 100644 --- a/src/VisualStudio/Core/Test/Progression/VisualBasicSymbolLabelTests.vb +++ b/src/VisualStudio/Core/Test/Progression/VisualBasicSymbolLabelTests.vb @@ -6,6 +6,7 @@ Imports Microsoft.VisualStudio.GraphModel Imports Roslyn.Test.Utilities Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Progression + <[UseExportProvider]> Public Class VisualBasicSymbolLabelTests Public Async Function TestMethodWithOptionalParameter() As Task diff --git a/src/VisualStudio/Core/Test/ProjectSystemShim/DeferredProjectLoadingTests.vb b/src/VisualStudio/Core/Test/ProjectSystemShim/DeferredProjectLoadingTests.vb index 7764930eb77bc..3f1a8c9aab703 100644 --- a/src/VisualStudio/Core/Test/ProjectSystemShim/DeferredProjectLoadingTests.vb +++ b/src/VisualStudio/Core/Test/ProjectSystemShim/DeferredProjectLoadingTests.vb @@ -7,6 +7,7 @@ Imports Microsoft.VisualStudio.LanguageServices.UnitTests.ProjectSystemShim.Visu Imports Roslyn.Test.Utilities Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.ProjectSystemShim + <[UseExportProvider]> Public Class DeferredProjectLoadingTests diff --git a/src/VisualStudio/Core/Test/ProjectSystemShim/VisualBasicCompilerOptionsTests.vb b/src/VisualStudio/Core/Test/ProjectSystemShim/VisualBasicCompilerOptionsTests.vb index 2f58b0f0f8a53..a2daf5809c2e9 100644 --- a/src/VisualStudio/Core/Test/ProjectSystemShim/VisualBasicCompilerOptionsTests.vb +++ b/src/VisualStudio/Core/Test/ProjectSystemShim/VisualBasicCompilerOptionsTests.vb @@ -8,6 +8,7 @@ Imports Microsoft.VisualStudio.LanguageServices.UnitTests.ProjectSystemShim.Visu Imports Roslyn.Test.Utilities Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.ProjectSystemShim + <[UseExportProvider]> Public Class VisualBasicCompilerOptions diff --git a/src/VisualStudio/Core/Test/ProjectSystemShim/VisualBasicProjectTests.vb b/src/VisualStudio/Core/Test/ProjectSystemShim/VisualBasicProjectTests.vb index 4afc5df19810a..de181777516d6 100644 --- a/src/VisualStudio/Core/Test/ProjectSystemShim/VisualBasicProjectTests.vb +++ b/src/VisualStudio/Core/Test/ProjectSystemShim/VisualBasicProjectTests.vb @@ -6,6 +6,7 @@ Imports Microsoft.VisualStudio.LanguageServices.UnitTests.ProjectSystemShim.Visu Imports Roslyn.Test.Utilities Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.ProjectSystemShim + <[UseExportProvider]> Public Class VisualBasicProjectTests diff --git a/src/VisualStudio/Core/Test/ProjectSystemShim/VisualBasicSpecialReferencesTests.vb b/src/VisualStudio/Core/Test/ProjectSystemShim/VisualBasicSpecialReferencesTests.vb index 388f3f6d0745a..924475a8771e3 100644 --- a/src/VisualStudio/Core/Test/ProjectSystemShim/VisualBasicSpecialReferencesTests.vb +++ b/src/VisualStudio/Core/Test/ProjectSystemShim/VisualBasicSpecialReferencesTests.vb @@ -7,6 +7,7 @@ Imports Microsoft.VisualStudio.LanguageServices.VisualBasic.ProjectSystemShim.In Imports Roslyn.Test.Utilities Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.ProjectSystemShim + <[UseExportProvider]> Public Class VisualBasicSpecialReferencesTests diff --git a/src/VisualStudio/Core/Test/RQName/RQNameTests.vb b/src/VisualStudio/Core/Test/RQName/RQNameTests.vb index f2821203c2b67..8b6dc9585217e 100644 --- a/src/VisualStudio/Core/Test/RQName/RQNameTests.vb +++ b/src/VisualStudio/Core/Test/RQName/RQNameTests.vb @@ -12,6 +12,7 @@ Imports Microsoft.CodeAnalysis.Test.Utilities Imports Roslyn.Test.Utilities Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.RQNameTests + <[UseExportProvider]> Public Class RQNameTests Public Async Function TestRQNameForNamespace() As Task diff --git a/src/VisualStudio/Core/Test/ServicesVisualStudioTest.vbproj b/src/VisualStudio/Core/Test/ServicesVisualStudioTest.vbproj index 75aff399e8206..2a97060a75e56 100644 --- a/src/VisualStudio/Core/Test/ServicesVisualStudioTest.vbproj +++ b/src/VisualStudio/Core/Test/ServicesVisualStudioTest.vbproj @@ -7,7 +7,7 @@ AnyCPU Library Roslyn.VisualStudio.Services.UnitTests - net461 + net46 $(RoslynDesktopRuntimeIdentifier) true UnitTest diff --git a/src/VisualStudio/Core/Test/Snippets/CSharpSnippetCommandHandlerTests.vb b/src/VisualStudio/Core/Test/Snippets/CSharpSnippetCommandHandlerTests.vb index 20405c890e25c..2c01fd12b2fe2 100644 --- a/src/VisualStudio/Core/Test/Snippets/CSharpSnippetCommandHandlerTests.vb +++ b/src/VisualStudio/Core/Test/Snippets/CSharpSnippetCommandHandlerTests.vb @@ -8,6 +8,7 @@ Imports Microsoft.VisualStudio.Text.Editor.Commanding.Commands Imports Roslyn.Test.Utilities Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Snippets + <[UseExportProvider]> Public Class CSharpSnippetCommandHandlerTests Public Sub SnippetCommandHandler_TabAtEndOfWord_NoActiveSession_ExpansionInserted() diff --git a/src/VisualStudio/Core/Test/Snippets/CSharpSnippetExpansionClientTests.vb b/src/VisualStudio/Core/Test/Snippets/CSharpSnippetExpansionClientTests.vb index 379ec5daca030..b67b995598d43 100644 --- a/src/VisualStudio/Core/Test/Snippets/CSharpSnippetExpansionClientTests.vb +++ b/src/VisualStudio/Core/Test/Snippets/CSharpSnippetExpansionClientTests.vb @@ -12,6 +12,7 @@ Imports Microsoft.VisualStudio.Text.Projection Imports Roslyn.Test.Utilities Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Snippets + <[UseExportProvider]> Public Class CSharpSnippetExpansionClientTests diff --git a/src/VisualStudio/Core/Test/Snippets/SnippetCompletionProviderTests.vb b/src/VisualStudio/Core/Test/Snippets/SnippetCompletionProviderTests.vb index e462e628caec6..a657f9febd6c9 100644 --- a/src/VisualStudio/Core/Test/Snippets/SnippetCompletionProviderTests.vb +++ b/src/VisualStudio/Core/Test/Snippets/SnippetCompletionProviderTests.vb @@ -11,6 +11,7 @@ Imports Roslyn.Test.Utilities Imports Roslyn.Utilities Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Snippets + <[UseExportProvider]> Public Class SnippetCompletionProviderTests Public Async Function SnippetCompletion() As Task diff --git a/src/VisualStudio/Core/Test/Snippets/SnippetTestState.vb b/src/VisualStudio/Core/Test/Snippets/SnippetTestState.vb index edff71c4ea6c6..8fc30a005a840 100644 --- a/src/VisualStudio/Core/Test/Snippets/SnippetTestState.vb +++ b/src/VisualStudio/Core/Test/Snippets/SnippetTestState.vb @@ -10,6 +10,7 @@ Imports Microsoft.CodeAnalysis.Editor.Shared.Options Imports Microsoft.CodeAnalysis.Editor.UnitTests Imports Microsoft.CodeAnalysis.Editor.UnitTests.IntelliSense Imports Microsoft.CodeAnalysis.Shared.TestHooks +Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.VisualStudio.Commanding Imports Microsoft.VisualStudio.Composition Imports Microsoft.VisualStudio.Editor @@ -68,7 +69,7 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Snippets Public Property SnippetExpansionClient As MockSnippetExpansionClient Private Shared Function CreatePartCatalog(types As IEnumerable(Of Type)) As ComposableCatalog - Return MinimalTestExportProvider.CreateTypeCatalog(types) + Return ExportProviderCache.CreateTypeCatalog(types) End Function Public Property CurrentCompletionPresenterSession As TestCompletionPresenterSession Implements IIntelliSenseTestState.CurrentCompletionPresenterSession diff --git a/src/VisualStudio/Core/Test/Snippets/VisualBasicSnippetCommandHandlerTests.vb b/src/VisualStudio/Core/Test/Snippets/VisualBasicSnippetCommandHandlerTests.vb index cf9afbfca1c92..ee2c1171682e0 100644 --- a/src/VisualStudio/Core/Test/Snippets/VisualBasicSnippetCommandHandlerTests.vb +++ b/src/VisualStudio/Core/Test/Snippets/VisualBasicSnippetCommandHandlerTests.vb @@ -9,6 +9,7 @@ Imports Microsoft.VisualStudio.Text.Editor.Commanding.Commands Imports Roslyn.Test.Utilities Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Snippets + <[UseExportProvider]> Public Class VisualBasicSnippetCommandHandlerTests Public Sub SnippetCommandHandler_TabAtEndOfWord_NoActiveSession_ExpansionInserted() diff --git a/src/VisualStudio/Core/Test/Snippets/VisualBasicSnippetExpansionClientTests.vb b/src/VisualStudio/Core/Test/Snippets/VisualBasicSnippetExpansionClientTests.vb index 37fac391eccfa..d1fdec84d21ff 100644 --- a/src/VisualStudio/Core/Test/Snippets/VisualBasicSnippetExpansionClientTests.vb +++ b/src/VisualStudio/Core/Test/Snippets/VisualBasicSnippetExpansionClientTests.vb @@ -12,6 +12,7 @@ Imports Microsoft.VisualStudio.Text.Projection Imports Roslyn.Test.Utilities Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Snippets + <[UseExportProvider]> Public Class VisualBasicSnippetExpansionClientTests Public Async Function TestAddImport_EmptyDocument() As Task diff --git a/src/VisualStudio/Core/Test/SolutionExplorer/AnalyzerItemTests.vb b/src/VisualStudio/Core/Test/SolutionExplorer/AnalyzerItemTests.vb index 61ef8974f7c9a..b88444f300f50 100644 --- a/src/VisualStudio/Core/Test/SolutionExplorer/AnalyzerItemTests.vb +++ b/src/VisualStudio/Core/Test/SolutionExplorer/AnalyzerItemTests.vb @@ -6,6 +6,7 @@ Imports Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplorer Imports Microsoft.VisualStudio.LanguageServices.SolutionExplorer Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.SolutionExplorer + <[UseExportProvider]> Public Class AnalyzerItemTests Public Sub Name() diff --git a/src/VisualStudio/Core/Test/SolutionExplorer/AnalyzerItemsSourceTests.vb b/src/VisualStudio/Core/Test/SolutionExplorer/AnalyzerItemsSourceTests.vb index 6c2bf9d16eb78..a4d5416c5666f 100644 --- a/src/VisualStudio/Core/Test/SolutionExplorer/AnalyzerItemsSourceTests.vb +++ b/src/VisualStudio/Core/Test/SolutionExplorer/AnalyzerItemsSourceTests.vb @@ -5,6 +5,7 @@ Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplorer Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.SolutionExplorer + <[UseExportProvider]> Public Class AnalyzerItemsSourceTests Public Sub Ordering() diff --git a/src/VisualStudio/Core/Test/SolutionExplorer/AnalyzersFolderItemTests.vb b/src/VisualStudio/Core/Test/SolutionExplorer/AnalyzersFolderItemTests.vb index 9292f62bdf68a..14ac80d12f3a0 100644 --- a/src/VisualStudio/Core/Test/SolutionExplorer/AnalyzersFolderItemTests.vb +++ b/src/VisualStudio/Core/Test/SolutionExplorer/AnalyzersFolderItemTests.vb @@ -6,6 +6,7 @@ Imports Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplorer Imports Microsoft.VisualStudio.LanguageServices.SolutionExplorer Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.SolutionExplorer + <[UseExportProvider]> Public Class AnalyzersFolderItemTests Public Sub Name() diff --git a/src/VisualStudio/Core/Test/SolutionExplorer/AnalyzersFolderProviderTests.vb b/src/VisualStudio/Core/Test/SolutionExplorer/AnalyzersFolderProviderTests.vb index 5ef4c31647ccf..e5b3d9d4813c3 100644 --- a/src/VisualStudio/Core/Test/SolutionExplorer/AnalyzersFolderProviderTests.vb +++ b/src/VisualStudio/Core/Test/SolutionExplorer/AnalyzersFolderProviderTests.vb @@ -10,6 +10,7 @@ Imports Microsoft.VisualStudio.Shell Imports Roslyn.Test.Utilities Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.SolutionExplorer + <[UseExportProvider]> Public Class AnalyzersFolderProviderTests diff --git a/src/VisualStudio/Core/Test/SymbolSearch/SymbolSearchUpdateEngineTests.vb b/src/VisualStudio/Core/Test/SymbolSearch/SymbolSearchUpdateEngineTests.vb index 79e220b2749ea..b024072bd1d9a 100644 --- a/src/VisualStudio/Core/Test/SymbolSearch/SymbolSearchUpdateEngineTests.vb +++ b/src/VisualStudio/Core/Test/SymbolSearch/SymbolSearchUpdateEngineTests.vb @@ -13,6 +13,7 @@ Imports Moq Imports Roslyn.Utilities Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.SymbolSearch + <[UseExportProvider]> Public Class SymbolSearchUpdateEngineTests Private Shared ReadOnly s_allButMoqExceptions As Func(Of Exception, Boolean) = Function(e) TypeOf e IsNot MockException diff --git a/src/VisualStudio/Core/Test/Venus/AbstractContainedLanguageCodeSupportTests.vb b/src/VisualStudio/Core/Test/Venus/AbstractContainedLanguageCodeSupportTests.vb index 36d922b2a5713..a11e96761bfab 100644 --- a/src/VisualStudio/Core/Test/Venus/AbstractContainedLanguageCodeSupportTests.vb +++ b/src/VisualStudio/Core/Test/Venus/AbstractContainedLanguageCodeSupportTests.vb @@ -1,12 +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. -Imports System.Threading.Tasks Imports Microsoft.CodeAnalysis Imports Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces +Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.VisualStudio.LanguageServices.Implementation.Venus Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Venus + <[UseExportProvider]> Public MustInherit Class AbstractContainedLanguageCodeSupportTests Protected MustOverride ReadOnly Property Language As String @@ -38,12 +39,12 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Venus Protected Function GetWorkspace(code As String) As TestWorkspace Return TestWorkspace.Create( - AssemblyName="Assembly" CommonReferences="true"> - -<%= code.Replace(vbCrLf, vbLf) %> - - -, exportProvider:=VisualStudioTestExportProvider.ExportProvider) + AssemblyName="Assembly" CommonReferences="true"> + + <%= code.Replace(vbCrLf, vbLf) %> + + +, exportProvider:=VisualStudioTestExportProvider.Factory.CreateExportProvider()) End Function Protected Function GetDocument(workspace As TestWorkspace) As Document diff --git a/src/VisualStudio/Core/Test/VsNavInfo/VsNavInfoTests.vb b/src/VisualStudio/Core/Test/VsNavInfo/VsNavInfoTests.vb index cd1c22224520f..a901dfe0a41d3 100644 --- a/src/VisualStudio/Core/Test/VsNavInfo/VsNavInfoTests.vb +++ b/src/VisualStudio/Core/Test/VsNavInfo/VsNavInfoTests.vb @@ -1,6 +1,7 @@ ' 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 System.Threading.Tasks +Imports Microsoft.CodeAnalysis.Editor.UnitTests Imports Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces Imports Microsoft.CodeAnalysis.FindSymbols Imports Microsoft.CodeAnalysis.Test.Utilities @@ -9,6 +10,7 @@ Imports Microsoft.VisualStudio.LanguageServices.UnitTests.Utilities.VsNavInfo Imports Microsoft.VisualStudio.Shell.Interop Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.VsNavInfo + <[UseExportProvider]> Public Class VsNavInfoTests #Region "C# Tests" @@ -816,7 +818,7 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.VsNavInfo Optional presentationNodes As NodeVerifier() = Nothing ) As Task - Using workspace = TestWorkspace.Create(workspaceDefinition, exportProvider:=VisualStudioTestExportProvider.ExportProvider) + Using workspace = TestWorkspace.Create(workspaceDefinition, exportProvider:=VisualStudioTestExportProvider.Factory.CreateExportProvider()) Dim hostDocument = workspace.DocumentWithCursor Assert.True(hostDocument IsNot Nothing, "Test defined without cursor position") @@ -854,7 +856,7 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.VsNavInfo Optional useExpandedHierarchy As Boolean = False ) As Task - Using workspace = TestWorkspace.Create(workspaceDefinition, exportProvider:=VisualStudioTestExportProvider.ExportProvider) + Using workspace = TestWorkspace.Create(workspaceDefinition, exportProvider:=VisualStudioTestExportProvider.Factory.CreateExportProvider()) Dim hostDocument = workspace.DocumentWithCursor Assert.True(hostDocument IsNot Nothing, "Test defined without cursor position") diff --git a/src/VisualStudio/IntegrationTest/IntegrationTests/AbstractEditorTest.cs b/src/VisualStudio/IntegrationTest/IntegrationTests/AbstractEditorTest.cs index f1b72f0a74ae4..5fde1b28020ef 100644 --- a/src/VisualStudio/IntegrationTest/IntegrationTests/AbstractEditorTest.cs +++ b/src/VisualStudio/IntegrationTest/IntegrationTests/AbstractEditorTest.cs @@ -1,8 +1,8 @@ // Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using System.Threading.Tasks; using Microsoft.VisualStudio.IntegrationTest.Utilities; using Microsoft.VisualStudio.IntegrationTest.Utilities.Common; -using Microsoft.VisualStudio.IntegrationTest.Utilities.OutOfProcess; using Roslyn.Test.Utilities; using ProjectUtils = Microsoft.VisualStudio.IntegrationTest.Utilities.Common.ProjectUtils; @@ -10,6 +10,9 @@ namespace Roslyn.VisualStudio.IntegrationTests { public abstract class AbstractEditorTest : AbstractIntegrationTest { + private readonly string _solutionName; + private readonly string _projectTemplate; + protected AbstractEditorTest(VisualStudioInstanceFactory instanceFactory) : base(instanceFactory) { @@ -26,22 +29,33 @@ protected AbstractEditorTest( string projectTemplate) : base(instanceFactory) { - VisualStudio.SolutionExplorer.CreateSolution(solutionName); - VisualStudio.SolutionExplorer.AddProject(new ProjectUtils.Project(ProjectName), projectTemplate, LanguageName); + _solutionName = solutionName; + _projectTemplate = projectTemplate; + } - // Winforms and XAML do not open text files on creation - // so these editor tasks will not work if that is the project template being used. - if (projectTemplate != WellKnownProjectTemplates.WinFormsApplication && - projectTemplate != WellKnownProjectTemplates.WpfApplication && - projectTemplate != WellKnownProjectTemplates.CSharpNetCoreClassLibrary) + protected abstract string LanguageName { get; } + + public override async Task InitializeAsync() + { + await base.InitializeAsync().ConfigureAwait(true); + + if (_solutionName != null) { - VisualStudio.Workspace.SetUseSuggestionMode(false); - ClearEditor(); + VisualStudio.SolutionExplorer.CreateSolution(_solutionName); + VisualStudio.SolutionExplorer.AddProject(new ProjectUtils.Project(ProjectName), _projectTemplate, LanguageName); + + // Winforms and XAML do not open text files on creation + // so these editor tasks will not work if that is the project template being used. + if (_projectTemplate != WellKnownProjectTemplates.WinFormsApplication && + _projectTemplate != WellKnownProjectTemplates.WpfApplication && + _projectTemplate != WellKnownProjectTemplates.CSharpNetCoreClassLibrary) + { + VisualStudio.Workspace.SetUseSuggestionMode(false); + ClearEditor(); + } } } - protected abstract string LanguageName { get; } - protected void ClearEditor() => SetUpEditor("$$"); diff --git a/src/VisualStudio/IntegrationTest/IntegrationTests/AbstractIntegrationTest.cs b/src/VisualStudio/IntegrationTest/IntegrationTests/AbstractIntegrationTest.cs index 8bb3d33f478a3..fe0427c280ba6 100644 --- a/src/VisualStudio/IntegrationTest/IntegrationTests/AbstractIntegrationTest.cs +++ b/src/VisualStudio/IntegrationTest/IntegrationTests/AbstractIntegrationTest.cs @@ -1,33 +1,73 @@ // Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; +using System.Runtime.InteropServices; using System.Threading; +using System.Threading.Tasks; +using Microsoft.VisualStudio; using Microsoft.VisualStudio.IntegrationTest.Utilities; using Microsoft.VisualStudio.IntegrationTest.Utilities.Input; +using Microsoft.Win32.SafeHandles; +using Xunit; +using IMessageFilter = Microsoft.VisualStudio.OLE.Interop.IMessageFilter; +using INTERFACEINFO = Microsoft.VisualStudio.OLE.Interop.INTERFACEINFO; +using PENDINGMSG = Microsoft.VisualStudio.OLE.Interop.PENDINGMSG; +using SERVERCALL = Microsoft.VisualStudio.OLE.Interop.SERVERCALL; namespace Roslyn.VisualStudio.IntegrationTests { [CaptureTestName] - public abstract class AbstractIntegrationTest : IDisposable + public abstract class AbstractIntegrationTest : IAsyncLifetime, IDisposable { /// /// A long timeout used to avoid hangs in tests, where a test failure manifests as an operation never occurring. /// protected static readonly TimeSpan HangMitigatingTimeout = TimeSpan.FromMinutes(1); - public readonly VisualStudioInstance VisualStudio; - protected readonly string ProjectName = "TestProj"; protected readonly string SolutionName = "TestSolution"; + private readonly MessageFilter _messageFilter; + private readonly VisualStudioInstanceFactory _instanceFactory; private VisualStudioInstanceContext _visualStudioContext; - protected AbstractIntegrationTest( - VisualStudioInstanceFactory instanceFactory) + protected AbstractIntegrationTest(VisualStudioInstanceFactory instanceFactory) + { + Assert.Equal(ApartmentState.STA, Thread.CurrentThread.GetApartmentState()); + + // Install a COM message filter to handle retry operations when the first attempt fails + _messageFilter = RegisterMessageFilter(); + _instanceFactory = instanceFactory; + + try + { + Helper.Automation.TransactionTimeout = 20000; + } + catch + { + _messageFilter.Dispose(); + throw; + } + } + + public VisualStudioInstance VisualStudio => _visualStudioContext?.Instance; + + public virtual async Task InitializeAsync() { - Helper.Automation.TransactionTimeout = 20000; - _visualStudioContext = instanceFactory.GetNewOrUsedInstance(SharedIntegrationHostFixture.RequiredPackageIds); - VisualStudio = _visualStudioContext.Instance; + try + { + _visualStudioContext = await _instanceFactory.GetNewOrUsedInstanceAsync(SharedIntegrationHostFixture.RequiredPackageIds).ConfigureAwait(false); + } + catch + { + _messageFilter.Dispose(); + throw; + } + } + + public Task DisposeAsync() + { + return Task.CompletedTask; } public void Dispose() @@ -36,6 +76,9 @@ public void Dispose() GC.SuppressFinalize(this); } + protected virtual MessageFilter RegisterMessageFilter() + => new MessageFilter(); + protected void Wait(double seconds) { var timeout = TimeSpan.FromMilliseconds(seconds * 1000); @@ -46,7 +89,14 @@ protected virtual void Dispose(bool disposing) { if (disposing) { - _visualStudioContext.Dispose(); + try + { + _visualStudioContext.Dispose(); + } + finally + { + _messageFilter.Dispose(); + } } } @@ -58,5 +108,110 @@ protected KeyPress Shift(VirtualKey virtualKey) protected KeyPress Alt(VirtualKey virtualKey) => new KeyPress(virtualKey, ShiftState.Alt); + + protected class MessageFilter : IMessageFilter, IDisposable + { + protected const uint CancelCall = ~0U; + + private readonly MessageFilterSafeHandle _messageFilterRegistration; + private readonly TimeSpan _timeout; + private readonly TimeSpan _retryDelay; + + public MessageFilter() + : this(timeout: TimeSpan.FromSeconds(60), retryDelay: TimeSpan.FromMilliseconds(150)) + { + } + + public MessageFilter(TimeSpan timeout, TimeSpan retryDelay) + { + _timeout = timeout; + _retryDelay = retryDelay; + _messageFilterRegistration = MessageFilterSafeHandle.Register(this); + } + + public virtual uint HandleInComingCall(uint dwCallType, IntPtr htaskCaller, uint dwTickCount, INTERFACEINFO[] lpInterfaceInfo) + { + return (uint)SERVERCALL.SERVERCALL_ISHANDLED; + } + + public virtual uint RetryRejectedCall(IntPtr htaskCallee, uint dwTickCount, uint dwRejectType) + { + if ((SERVERCALL)dwRejectType != SERVERCALL.SERVERCALL_RETRYLATER + && (SERVERCALL)dwRejectType != SERVERCALL.SERVERCALL_REJECTED) + { + return CancelCall; + } + + if (dwTickCount >= _timeout.TotalMilliseconds) + { + return CancelCall; + } + + return (uint)_retryDelay.TotalMilliseconds; + } + + public virtual uint MessagePending(IntPtr htaskCallee, uint dwTickCount, uint dwPendingType) + { + return (uint)PENDINGMSG.PENDINGMSG_WAITDEFPROCESS; + } + + protected virtual void Dispose(bool disposing) + { + if (disposing) + { + _messageFilterRegistration.Dispose(); + } + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + } + + private sealed class MessageFilterSafeHandle : SafeHandleMinusOneIsInvalid + { + private readonly IntPtr _oldFilter; + + private MessageFilterSafeHandle(IntPtr handle) + : base(true) + { + SetHandle(handle); + + try + { + if (CoRegisterMessageFilter(handle, out _oldFilter) != VSConstants.S_OK) + { + throw new InvalidOperationException("Failed to register a new message filter"); + } + } + catch + { + SetHandleAsInvalid(); + throw; + } + } + + [DllImport("ole32", SetLastError = true)] + private static extern int CoRegisterMessageFilter(IntPtr messageFilter, out IntPtr oldMessageFilter); + + public static MessageFilterSafeHandle Register(T messageFilter) + where T : IMessageFilter + { + var handle = Marshal.GetComInterfaceForObject(messageFilter); + return new MessageFilterSafeHandle(handle); + } + + protected override bool ReleaseHandle() + { + if (CoRegisterMessageFilter(_oldFilter, out _) == VSConstants.S_OK) + { + Marshal.Release(handle); + } + + return true; + } + } } } diff --git a/src/VisualStudio/IntegrationTest/IntegrationTests/AbstractInteractiveWindowTest.cs b/src/VisualStudio/IntegrationTest/IntegrationTests/AbstractInteractiveWindowTest.cs index 421527c6c1199..0c4ea08e1dac2 100644 --- a/src/VisualStudio/IntegrationTest/IntegrationTests/AbstractInteractiveWindowTest.cs +++ b/src/VisualStudio/IntegrationTest/IntegrationTests/AbstractInteractiveWindowTest.cs @@ -1,7 +1,7 @@ // Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using System.Threading.Tasks; using Microsoft.VisualStudio.IntegrationTest.Utilities; -using Microsoft.VisualStudio.IntegrationTest.Utilities.OutOfProcess; namespace Roslyn.VisualStudio.IntegrationTests { @@ -10,6 +10,11 @@ public abstract class AbstractInteractiveWindowTest : AbstractIntegrationTest protected AbstractInteractiveWindowTest(VisualStudioInstanceFactory instanceFactory) : base(instanceFactory) { + } + + public override async Task InitializeAsync() + { + await base.InitializeAsync().ConfigureAwait(true); ClearInteractiveWindow(); } diff --git a/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpAddMissingReference.cs b/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpAddMissingReference.cs index 4ca8386191cd4..8c09a9e87afc4 100644 --- a/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpAddMissingReference.cs +++ b/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpAddMissingReference.cs @@ -1,9 +1,11 @@ // Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using System.Threading.Tasks; using System.Xml.Linq; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Test.Utilities; using Microsoft.VisualStudio.IntegrationTest.Utilities; +using Roslyn.Test.Utilities; using Xunit; using ProjectUtils = Microsoft.VisualStudio.IntegrationTest.Utilities.Common.ProjectUtils; @@ -103,6 +105,11 @@ static void Main(string[] args) public CSharpAddMissingReference(VisualStudioInstanceFactory instanceFactory) : base(instanceFactory) { + } + + public override async Task InitializeAsync() + { + await base.InitializeAsync().ConfigureAwait(true); VisualStudio.SolutionExplorer.CreateSolution("ReferenceErrors", solutionElement: XElement.Parse( "" + $" " + @@ -132,7 +139,7 @@ public CSharpAddMissingReference(VisualStudioInstanceFactory instanceFactory) "")); } - [Fact, Trait(Traits.Feature, Traits.Features.AddMissingReference)] + [WpfFact, Trait(Traits.Feature, Traits.Features.AddMissingReference)] public void VerifyAvailableCodeActions() { var consoleProject = new ProjectUtils.Project(ConsoleProjectName); @@ -148,7 +155,7 @@ public void VerifyAvailableCodeActions() VisualStudio.Editor.Verify.CodeAction("Add project reference to 'ClassLibrary3'.", applyFix: false); } - [Fact, Trait(Traits.Feature, Traits.Features.AddMissingReference)] + [WpfFact, Trait(Traits.Feature, Traits.Features.AddMissingReference)] public void InvokeSomeFixesInCSharpThenVerifyReferences() { var consoleProject = new ProjectUtils.Project(ConsoleProjectName); diff --git a/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpAutomaticBraceCompletion.cs b/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpAutomaticBraceCompletion.cs index 2db1cb29422be..f34f93d5e6554 100644 --- a/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpAutomaticBraceCompletion.cs +++ b/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpAutomaticBraceCompletion.cs @@ -19,7 +19,7 @@ public CSharpAutomaticBraceCompletion(VisualStudioInstanceFactory instanceFactor { } - [Fact, Trait(Traits.Feature, Traits.Features.AutomaticCompletion)] + [WpfFact, Trait(Traits.Feature, Traits.Features.AutomaticCompletion)] public void Braces_InsertionAndTabCompleting() { SetUpEditor(@" @@ -36,7 +36,7 @@ void Goo() { VisualStudio.Editor.Verify.CurrentLineText("if (true) { }$$", assertCaretPosition: true); } - [Fact, Trait(Traits.Feature, Traits.Features.AutomaticCompletion)] + [WpfFact, Trait(Traits.Feature, Traits.Features.AutomaticCompletion)] public void Braces_Overtyping() { SetUpEditor(@" @@ -53,7 +53,7 @@ void Goo() { VisualStudio.Editor.Verify.CurrentLineText("if (true) { }$$", assertCaretPosition: true); } - [Fact, Trait(Traits.Feature, Traits.Features.AutomaticCompletion)] + [WpfFact, Trait(Traits.Feature, Traits.Features.AutomaticCompletion)] public void Braces_OnReturnNoFormattingOnlyIndentationBeforeCloseBrace() { SetUpEditor(@" @@ -80,7 +80,7 @@ void Goo() { assertCaretPosition: true); } - [Fact, Trait(Traits.Feature, Traits.Features.AutomaticCompletion)] + [WpfFact, Trait(Traits.Feature, Traits.Features.AutomaticCompletion)] public void Braces_OnReturnOvertypingTheClosingBrace() { SetUpEditor(@" @@ -109,7 +109,7 @@ void Goo() { } [WorkItem(653540, "DevDiv")] - [Fact, Trait(Traits.Feature, Traits.Features.AutomaticCompletion)] + [WpfFact, Trait(Traits.Feature, Traits.Features.AutomaticCompletion)] public void Braces_OnReturnWithNonWhitespaceSpanInside() { VisualStudio.Editor.SendKeys( @@ -121,7 +121,7 @@ public void Braces_OnReturnWithNonWhitespaceSpanInside() assertCaretPosition: true); } - [Fact, Trait(Traits.Feature, Traits.Features.AutomaticCompletion)] + [WpfFact, Trait(Traits.Feature, Traits.Features.AutomaticCompletion)] public void Paren_InsertionAndTabCompleting() { SetUpEditor(@" @@ -136,7 +136,7 @@ class C { VisualStudio.Editor.Verify.CurrentLineText("void Goo(int x)$$", assertCaretPosition: true); } - [Fact, Trait(Traits.Feature, Traits.Features.AutomaticCompletion)] + [WpfFact, Trait(Traits.Feature, Traits.Features.AutomaticCompletion)] public void Paren_Overtyping() { SetUpEditor(@" @@ -152,7 +152,7 @@ class C { VisualStudio.Editor.Verify.CurrentLineText("void Goo()$$", assertCaretPosition: true); } - [Fact, Trait(Traits.Feature, Traits.Features.AutomaticCompletion)] + [WpfFact, Trait(Traits.Feature, Traits.Features.AutomaticCompletion)] public void SquareBracket_Insertion() { SetUpEditor(@" @@ -164,7 +164,7 @@ class C { VisualStudio.Editor.Verify.CurrentLineText("int [$$]", assertCaretPosition: true); } - [Fact, Trait(Traits.Feature, Traits.Features.AutomaticCompletion)] + [WpfFact, Trait(Traits.Feature, Traits.Features.AutomaticCompletion)] public void SquareBracket_Overtyping() { SetUpEditor(@" @@ -176,7 +176,7 @@ class C { VisualStudio.Editor.Verify.CurrentLineText("int []$$", assertCaretPosition: true); } - [Fact, Trait(Traits.Feature, Traits.Features.AutomaticCompletion)] + [WpfFact, Trait(Traits.Feature, Traits.Features.AutomaticCompletion)] public void DoubleQuote_InsertionAndTabCompletion() { SetUpEditor(@" @@ -188,7 +188,7 @@ class C { VisualStudio.Editor.Verify.CurrentLineText("string str = \"\"$$", assertCaretPosition: true); } - [Fact, Trait(Traits.Feature, Traits.Features.AutomaticCompletion)] + [WpfFact, Trait(Traits.Feature, Traits.Features.AutomaticCompletion)] public void DoubleQuote_InsertionAndOvertyping() { SetUpEditor(@" @@ -200,7 +200,7 @@ class C { VisualStudio.Editor.Verify.CurrentLineText("string str = \"Hi Roslyn!\"$$", assertCaretPosition: true); } - [Fact, Trait(Traits.Feature, Traits.Features.AutomaticCompletion)] + [WpfFact, Trait(Traits.Feature, Traits.Features.AutomaticCompletion)] public void AngleBracket_PossibleGenerics_InsertionAndCompletion() { SetUpEditor(@" @@ -247,7 +247,7 @@ class C { VisualStudio.Editor.Verify.CurrentLineText("class GenericClass<>$$", assertCaretPosition: true); } - [Fact, Trait(Traits.Feature, Traits.Features.AutomaticCompletion)] + [WpfFact, Trait(Traits.Feature, Traits.Features.AutomaticCompletion)] public void SingleQuote_InsertionAndCompletion() { SetUpEditor(@" @@ -264,7 +264,7 @@ class C { VisualStudio.Editor.Verify.CurrentLineText("char c = '\u6666'$$", assertCaretPosition: true); } - [Fact, Trait(Traits.Feature, Traits.Features.AutomaticCompletion)] + [WpfFact, Trait(Traits.Feature, Traits.Features.AutomaticCompletion)] public void Nested_AllKinds() { SetUpEditor(@" @@ -292,7 +292,7 @@ void M() VisualStudio.Editor.Verify.CurrentLineText("var arr = new object[,] { { Goo(0) }, { Goo(Goo(\"hello\")) } };$$", assertCaretPosition: true); } - [Fact, Trait(Traits.Feature, Traits.Features.AutomaticCompletion)] + [WpfFact, Trait(Traits.Feature, Traits.Features.AutomaticCompletion)] public void Negative_NoCompletionInSingleLineComments() { SetUpEditor(@" @@ -304,7 +304,7 @@ class C { VisualStudio.Editor.Verify.CurrentLineText("// {([\"'$$", assertCaretPosition: true); } - [Fact, Trait(Traits.Feature, Traits.Features.AutomaticCompletion)] + [WpfFact, Trait(Traits.Feature, Traits.Features.AutomaticCompletion)] public void Negative_NoCompletionInMultiLineComments() { SetUpEditor(@" @@ -318,7 +318,7 @@ class C { VisualStudio.Editor.Verify.CurrentLineText("{([\"'$$", assertCaretPosition: true); } - [Fact, Trait(Traits.Feature, Traits.Features.AutomaticCompletion)] + [WpfFact, Trait(Traits.Feature, Traits.Features.AutomaticCompletion)] public void Negative_NoCompletionStringVerbatimStringOrCharLiterals() { SetUpEditor(@" @@ -340,7 +340,7 @@ class C { VisualStudio.Editor.Verify.CurrentLineText("char ch = '{([<\"'$$", assertCaretPosition: true); } - [Fact, Trait(Traits.Feature, Traits.Features.AutomaticCompletion)] + [WpfFact, Trait(Traits.Feature, Traits.Features.AutomaticCompletion)] public void Negative_NoCompletionInXmlDocComments() { SetUpEditor(@" @@ -354,7 +354,7 @@ class C { }"); VisualStudio.Editor.Verify.CurrentLineText("/// {([<\"'$$", assertCaretPosition: true); } - [Fact, Trait(Traits.Feature, Traits.Features.AutomaticCompletion)] + [WpfFact, Trait(Traits.Feature, Traits.Features.AutomaticCompletion)] public void Negative_NoCompletionInDisabledPreprocesser() { SetUpEditor(@" @@ -368,7 +368,7 @@ class C { VisualStudio.Editor.Verify.CurrentLineText("void Goo($$", assertCaretPosition: true); } - [Fact, Trait(Traits.Feature, Traits.Features.AutomaticCompletion)] + [WpfFact, Trait(Traits.Feature, Traits.Features.AutomaticCompletion)] public void Negative_NoCompletionAfterRegionPreprocesser() { SetUpEditor(@" @@ -381,7 +381,7 @@ public void Negative_NoCompletionAfterRegionPreprocesser() VisualStudio.Editor.Verify.CurrentLineText("#region {([<\"'$$", assertCaretPosition: true); } - [Fact, Trait(Traits.Feature, Traits.Features.AutomaticCompletion)] + [WpfFact, Trait(Traits.Feature, Traits.Features.AutomaticCompletion)] public void Negative_NoCompletionAfterEndregionPreprocesser() { SetUpEditor(@" @@ -394,7 +394,7 @@ public void Negative_NoCompletionAfterEndregionPreprocesser() VisualStudio.Editor.Verify.CurrentLineText("#endregion {([<\"'$$", assertCaretPosition: true); } - [Fact, Trait(Traits.Feature, Traits.Features.AutomaticCompletion)] + [WpfFact, Trait(Traits.Feature, Traits.Features.AutomaticCompletion)] public void Negative_NoCompletionAfterIfPreprocesser() { SetUpEditor(@" @@ -405,7 +405,7 @@ public void Negative_NoCompletionAfterIfPreprocesser() VisualStudio.Editor.Verify.CurrentLineText("#if {([<\"'$$", assertCaretPosition: true); } - [Fact, Trait(Traits.Feature, Traits.Features.AutomaticCompletion)] + [WpfFact, Trait(Traits.Feature, Traits.Features.AutomaticCompletion)] public void Negative_NoCompletionAfterPragmaPreprocesser() { SetUpEditor(@" @@ -417,7 +417,7 @@ public void Negative_NoCompletionAfterPragmaPreprocesser() } [WorkItem(651954, "DevDiv")] - [Fact, Trait(Traits.Feature, Traits.Features.AutomaticCompletion)] + [WpfFact, Trait(Traits.Feature, Traits.Features.AutomaticCompletion)] public void InteractionWithOverrideStubGeneration() { SetUpEditor(@" @@ -446,7 +446,7 @@ public override void Goo() } [WorkItem(531107, "DevDiv")] - [Fact, Trait(Traits.Feature, Traits.Features.AutomaticCompletion)] + [WpfFact, Trait(Traits.Feature, Traits.Features.AutomaticCompletion)] public void InteractionWithCompletionList() { SetUpEditor(@" @@ -465,7 +465,7 @@ void M() } [WorkItem(823958, "DevDiv")] - [Fact, Trait(Traits.Feature, Traits.Features.AutomaticCompletion)] + [WpfFact, Trait(Traits.Feature, Traits.Features.AutomaticCompletion)] public void AutoBraceCompleteDoesNotFormatBracePairInInitializers() { SetUpEditor(@" @@ -483,7 +483,7 @@ void M() } [WorkItem(823958, "DevDiv")] - [Fact, Trait(Traits.Feature, Traits.Features.AutomaticCompletion)] + [WpfFact, Trait(Traits.Feature, Traits.Features.AutomaticCompletion)] public void AutoBraceCompleteDoesNotFormatBracePairInObjectCreationExpression() { SetUpEditor(@" @@ -501,7 +501,7 @@ void M() } [WorkItem(823958, "DevDiv")] - [Fact, Trait(Traits.Feature, Traits.Features.AutomaticCompletion)] + [WpfFact, Trait(Traits.Feature, Traits.Features.AutomaticCompletion)] public void AutoBraceCompleteFormatsBracePairInClassDeclarationAndAutoProperty() { SetUpEditor(@" diff --git a/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpBuild.cs b/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpBuild.cs index 27063023750bd..119d8e98ba9e7 100644 --- a/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpBuild.cs +++ b/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpBuild.cs @@ -2,9 +2,11 @@ using System.Diagnostics; using System.IO; +using System.Threading.Tasks; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Test.Utilities; using Microsoft.VisualStudio.IntegrationTest.Utilities; +using Roslyn.Test.Utilities; using Xunit; using ProjectUtils = Microsoft.VisualStudio.IntegrationTest.Utilities.Common.ProjectUtils; @@ -16,11 +18,16 @@ public class CSharpBuild : AbstractIntegrationTest public CSharpBuild(VisualStudioInstanceFactory instanceFactory) : base(instanceFactory) { + } + + public override async Task InitializeAsync() + { + await base.InitializeAsync().ConfigureAwait(true); VisualStudio.SolutionExplorer.CreateSolution(nameof(CSharpBuild)); VisualStudio.SolutionExplorer.AddProject(new ProjectUtils.Project("TestProj"), WellKnownProjectTemplates.ConsoleApplication, LanguageNames.CSharp); } - [Fact, Trait(Traits.Feature, Traits.Features.Build)] + [WpfFact, Trait(Traits.Feature, Traits.Features.Build)] public void BuildProject() { var editorText = @"using System; @@ -38,7 +45,7 @@ static void Main(string[] args) // TODO: Validate build works as expected } - [Fact(Skip = "https://github.com/dotnet/roslyn/issues/18204"), Trait(Traits.Feature, Traits.Features.Build)] + [WpfFact(Skip = "https://github.com/dotnet/roslyn/issues/18204"), Trait(Traits.Feature, Traits.Features.Build)] public void BuildWithCommandLine() { VisualStudio.SolutionExplorer.SaveAll(); diff --git a/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpChangeSignatureDialog.cs b/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpChangeSignatureDialog.cs index b31218356bc25..332602a12b5c1 100644 --- a/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpChangeSignatureDialog.cs +++ b/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpChangeSignatureDialog.cs @@ -4,6 +4,7 @@ using Microsoft.CodeAnalysis.Test.Utilities; using Microsoft.VisualStudio.IntegrationTest.Utilities; using Microsoft.VisualStudio.IntegrationTest.Utilities.OutOfProcess; +using Roslyn.Test.Utilities; using Xunit; using ProjectUtils = Microsoft.VisualStudio.IntegrationTest.Utilities.Common.ProjectUtils; @@ -21,7 +22,7 @@ public CSharpChangeSignatureDialog(VisualStudioInstanceFactory instanceFactory) { } - [Fact, Trait(Traits.Feature, Traits.Features.ChangeSignature)] + [WpfFact, Trait(Traits.Feature, Traits.Features.ChangeSignature)] public void VerifyCodeRefactoringOffered() { SetUpEditor(@" @@ -34,7 +35,7 @@ class C VisualStudio.Editor.Verify.CodeAction("Change signature...", applyFix: false); } - [Fact, Trait(Traits.Feature, Traits.Features.ChangeSignature)] + [WpfFact, Trait(Traits.Feature, Traits.Features.ChangeSignature)] public void VerifyRefactoringCancelled() { SetUpEditor(@" @@ -55,7 +56,7 @@ public void Method(int a, string b) { } }", actualText); } - [Fact, Trait(Traits.Feature, Traits.Features.ChangeSignature)] + [WpfFact, Trait(Traits.Feature, Traits.Features.ChangeSignature)] public void VerifyReorderParameters() { SetUpEditor(@" @@ -78,7 +79,7 @@ public void Method(string b, int a) { } }", actuaText); } - [Fact, Trait(Traits.Feature, Traits.Features.ChangeSignature)] + [WpfFact, Trait(Traits.Feature, Traits.Features.ChangeSignature)] public void VerifyRemoveParameter() { SetUpEditor(@" @@ -122,7 +123,7 @@ void Test() }", actuaText); } - [Fact, Trait(Traits.Feature, Traits.Features.ChangeSignature)] + [WpfFact, Trait(Traits.Feature, Traits.Features.ChangeSignature)] public void VerifyCrossLanguageGlobalUndo() { SetUpEditor(@"using VBProject; diff --git a/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpClassification.cs b/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpClassification.cs index 91ee97508bfad..3c84526938e38 100644 --- a/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpClassification.cs +++ b/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpClassification.cs @@ -3,6 +3,7 @@ using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Test.Utilities; using Microsoft.VisualStudio.IntegrationTest.Utilities; +using Roslyn.Test.Utilities; using Xunit; namespace Roslyn.VisualStudio.IntegrationTests.CSharp @@ -17,7 +18,7 @@ public CSharpClassification(VisualStudioInstanceFactory instanceFactory) { } - [Fact, Trait(Traits.Feature, Traits.Features.Classification)] + [WpfFact, Trait(Traits.Feature, Traits.Features.Classification)] public void VerifyColorOfSomeTokens() { VisualStudio.Editor.SetText(@"using System; @@ -65,7 +66,7 @@ public static void Main(string[] args) VisualStudio.Editor.Verify.CurrentTokenType(tokenType: "identifier"); } - [Fact, Trait(Traits.Feature, Traits.Features.Classification)] + [WpfFact, Trait(Traits.Feature, Traits.Features.Classification)] public void SemanticClassification() { VisualStudio.Editor.SetText(@" @@ -100,7 +101,7 @@ static void Main(string[] args) VisualStudio.Editor.Verify.CurrentTokenType(tokenType: "class name"); } - [Fact, Trait(Traits.Feature, Traits.Features.Classification)] + [WpfFact, Trait(Traits.Feature, Traits.Features.Classification)] public void VerifyProjectConfigChange() { VisualStudio.Editor.SetText(@" diff --git a/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpCodeActions.cs b/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpCodeActions.cs index 6ac8dc8c25eae..0107138fea71c 100644 --- a/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpCodeActions.cs +++ b/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpCodeActions.cs @@ -23,7 +23,7 @@ public CSharpCodeActions(VisualStudioInstanceFactory instanceFactory) { } - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateMethod)] + [WpfFact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateMethod)] public void GenerateMethodInClosedFile() { var project = new ProjectUtils.Project(ProjectName); @@ -61,7 +61,7 @@ internal void Bar() "); } - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddImport)] + [WpfFact, Trait(Traits.Feature, Traits.Features.CodeActionsAddImport)] public void FastDoubleInvoke() { // We want to invoke the first smart tag and then *immediately * try invoking the next. @@ -96,7 +96,7 @@ static void Main(string[] args) }"); } - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsInvokeDelegateWithConditionalAccess)] + [WpfFact, Trait(Traits.Feature, Traits.Features.CodeActionsInvokeDelegateWithConditionalAccess)] public void InvokeDelegateWithConditionalAccessMultipleTimes() { var markup = @" @@ -135,7 +135,7 @@ void RaiseSecond() VisualStudio.Editor.Verify.TextContains("Second?."); } - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateMethod)] + [WpfFact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateMethod)] public void ClassificationInPreviewPane() { SetUpEditor(@" @@ -151,7 +151,7 @@ int Main() Assert.True(classifiedTokens.Any(c => c.Text == "void" && c.Classification == "keyword")); } - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddImport)] + [WpfFact, Trait(Traits.Feature, Traits.Features.CodeActionsAddImport)] public void AddUsingExactMatchBeforeRenameTracking() { SetUpEditor(@" @@ -185,7 +185,7 @@ public class P2 { }"); VisualStudio.Editor.Verify.TextContains("using System.IO;"); } - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateType)] + [WpfFact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateType)] public void GFUFuzzyMatchAfterRenameTracking() { SetUpEditor(@" @@ -224,7 +224,7 @@ static void Main(string[] args) VisualStudio.Editor.Verify.CodeActions(expectedItems, applyFix: expectedItems[0], ensureExpectedItemsAreOrdered: true); } - [Fact, Trait(Traits.Feature, Traits.Features.CodeGeneration)] + [WpfFact, Trait(Traits.Feature, Traits.Features.CodeGeneration)] public void SuppressionAfterRefactorings() { SetUpEditor(@" @@ -258,7 +258,7 @@ static void Main(string[] args) VisualStudio.Editor.Verify.TextContains("implicit"); } - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddImport)] + [WpfFact, Trait(Traits.Feature, Traits.Features.CodeActionsAddImport)] public void OrderFixesByCursorProximityLeft() { SetUpEditor(@" @@ -282,7 +282,7 @@ static void Main(string[] args) VisualStudio.Editor.Verify.TextContains("using System.Runtime.InteropServices"); } - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddImport)] + [WpfFact, Trait(Traits.Feature, Traits.Features.CodeActionsAddImport)] public void OrderFixesByCursorProximityRight() { SetUpEditor(@" diff --git a/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpEncapsulateField.cs b/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpEncapsulateField.cs index 50b9f2727c352..e48b0a0dca549 100644 --- a/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpEncapsulateField.cs +++ b/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpEncapsulateField.cs @@ -1,10 +1,10 @@ // Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using System; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Shared.TestHooks; using Microsoft.CodeAnalysis.Test.Utilities; using Microsoft.VisualStudio.IntegrationTest.Utilities; +using Roslyn.Test.Utilities; using Xunit; namespace Roslyn.VisualStudio.IntegrationTests.CSharp @@ -32,7 +32,8 @@ static void Main(string[] args) } }"; - [Fact, Trait(Traits.Feature, Traits.Features.EncapsulateField)] + [WpfFact(Skip = "https://github.com/dotnet/roslyn/issues/19816")] + [Trait(Traits.Feature, Traits.Features.EncapsulateField)] public void EncapsulateThroughCommand() { SetUpEditor(TestSource); @@ -48,7 +49,7 @@ public void EncapsulateThroughCommand() VisualStudio.Editor.Verify.TextContains("public static int? Param { get => param; set => param = value; }"); } - [Fact, Trait(Traits.Feature, Traits.Features.EncapsulateField)] + [WpfFact, Trait(Traits.Feature, Traits.Features.EncapsulateField)] public void EncapsulateThroughLightbulbIncludingReferences() { SetUpEditor(TestSource); @@ -71,7 +72,7 @@ static void Main(string[] args) }"); } - [Fact, Trait(Traits.Feature, Traits.Features.EncapsulateField)] + [WpfFact, Trait(Traits.Feature, Traits.Features.EncapsulateField)] public void EncapsulateThroughLightbulbDefinitionsOnly() { SetUpEditor(TestSource); diff --git a/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpErrorListDesktop.cs b/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpErrorListDesktop.cs index 878bc37e995dd..916fabb3508ed 100644 --- a/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpErrorListDesktop.cs +++ b/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpErrorListDesktop.cs @@ -2,6 +2,7 @@ using Microsoft.CodeAnalysis.Test.Utilities; using Microsoft.VisualStudio.IntegrationTest.Utilities; +using Roslyn.Test.Utilities; using Xunit; namespace Roslyn.VisualStudio.IntegrationTests.CSharp @@ -14,19 +15,19 @@ public CSharpErrorListDesktop(VisualStudioInstanceFactory instanceFactory) { } - [Fact(Skip = "https://github.com/dotnet/roslyn/issues/18996"), Trait(Traits.Feature, Traits.Features.ErrorList)] + [WpfFact(Skip = "https://github.com/dotnet/roslyn/issues/18996"), Trait(Traits.Feature, Traits.Features.ErrorList)] public override void ErrorList() { base.ErrorList(); } - [Fact(Skip = "https://github.com/dotnet/roslyn/issues/18996"), Trait(Traits.Feature, Traits.Features.ErrorList)] + [WpfFact(Skip = "https://github.com/dotnet/roslyn/issues/18996"), Trait(Traits.Feature, Traits.Features.ErrorList)] public override void ErrorLevelWarning() { base.ErrorLevelWarning(); } - [Fact, Trait(Traits.Feature, Traits.Features.ErrorList)] + [WpfFact, Trait(Traits.Feature, Traits.Features.ErrorList)] public override void ErrorsDuringMethodBodyEditing() { base.ErrorsDuringMethodBodyEditing(); diff --git a/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpErrorListNetCore.cs b/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpErrorListNetCore.cs index 8ffd84a7d2920..7230b4435b8c3 100644 --- a/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpErrorListNetCore.cs +++ b/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpErrorListNetCore.cs @@ -2,6 +2,7 @@ using Microsoft.CodeAnalysis.Test.Utilities; using Microsoft.VisualStudio.IntegrationTest.Utilities; +using Roslyn.Test.Utilities; using Xunit; namespace Roslyn.VisualStudio.IntegrationTests.CSharp @@ -14,21 +15,21 @@ public CSharpErrorListNetCore(VisualStudioInstanceFactory instanceFactory) { } - [Fact(Skip = "https://github.com/dotnet/roslyn/issues/18996"), Trait(Traits.Feature, Traits.Features.ErrorList)] + [WpfFact(Skip = "https://github.com/dotnet/roslyn/issues/18996"), Trait(Traits.Feature, Traits.Features.ErrorList)] [Trait(Traits.Feature, Traits.Features.NetCore)] public override void ErrorList() { base.ErrorList(); } - [Fact(Skip = "https://github.com/dotnet/roslyn/issues/18996"), Trait(Traits.Feature, Traits.Features.ErrorList)] + [WpfFact(Skip = "https://github.com/dotnet/roslyn/issues/18996"), Trait(Traits.Feature, Traits.Features.ErrorList)] [Trait(Traits.Feature, Traits.Features.NetCore)] public override void ErrorLevelWarning() { base.ErrorLevelWarning(); } - [Fact(Skip = "https://github.com/dotnet/roslyn/issues/19090"), Trait(Traits.Feature, Traits.Features.ErrorList)] + [WpfFact(Skip = "https://github.com/dotnet/roslyn/issues/19090"), Trait(Traits.Feature, Traits.Features.ErrorList)] [Trait(Traits.Feature, Traits.Features.NetCore)] public override void ErrorsDuringMethodBodyEditing() { diff --git a/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpExtractInterfaceDialog.cs b/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpExtractInterfaceDialog.cs index 37d70f77e961f..baf0fd20e048a 100644 --- a/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpExtractInterfaceDialog.cs +++ b/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpExtractInterfaceDialog.cs @@ -4,6 +4,7 @@ using Microsoft.CodeAnalysis.Test.Utilities; using Microsoft.VisualStudio.IntegrationTest.Utilities; using Microsoft.VisualStudio.IntegrationTest.Utilities.OutOfProcess; +using Roslyn.Test.Utilities; using Xunit; using ProjectUtils = Microsoft.VisualStudio.IntegrationTest.Utilities.Common.ProjectUtils; @@ -21,7 +22,7 @@ public CSharpExtractInterfaceDialog(VisualStudioInstanceFactory instanceFactory) { } - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsExtractInterface)] + [WpfFact, Trait(Traits.Feature, Traits.Features.CodeActionsExtractInterface)] public void VerifyCancellation() { SetUpEditor(@"class C$$ @@ -45,7 +46,7 @@ public void M() { } "); } - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsExtractInterface)] + [WpfFact, Trait(Traits.Feature, Traits.Features.CodeActionsExtractInterface)] public void CheckFileName() { SetUpEditor(@"class C$$ @@ -67,7 +68,7 @@ public void M() { } ExtractInterfaceDialog.VerifyClosed(); } - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsExtractInterface)] + [WpfFact, Trait(Traits.Feature, Traits.Features.CodeActionsExtractInterface)] public void VerifySelectAndDeselectAllButtons() { SetUpEditor(@"class C$$ @@ -105,7 +106,7 @@ public void M2() { } ExtractInterfaceDialog.VerifyClosed(); } - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsExtractInterface)] + [WpfFact, Trait(Traits.Feature, Traits.Features.CodeActionsExtractInterface)] public void OnlySelectedItemsAreGenerated() { SetUpEditor(@"class C$$ diff --git a/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpExtractMethod.cs b/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpExtractMethod.cs index 48c4055f9d01d..21c2488a217d3 100644 --- a/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpExtractMethod.cs +++ b/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpExtractMethod.cs @@ -38,7 +38,7 @@ public CSharpExtractMethod(VisualStudioInstanceFactory instanceFactory) { } - [Fact, Trait(Traits.Feature, Traits.Features.ExtractMethod)] + [WpfFact, Trait(Traits.Feature, Traits.Features.ExtractMethod)] public void SimpleExtractMethod() { VisualStudio.Editor.SetText(TestSource); @@ -79,7 +79,7 @@ public int Method() }"); } - [Fact, Trait(Traits.Feature, Traits.Features.ExtractMethod)] + [WpfFact, Trait(Traits.Feature, Traits.Features.ExtractMethod)] public void ExtractViaCodeAction() { VisualStudio.Editor.SetText(TestSource); @@ -114,7 +114,7 @@ public int Method() AssertEx.SetEqual(spans, VisualStudio.Editor.GetTagSpans(VisualStudio.InlineRenameDialog.ValidRenameTag)); } - [Fact, Trait(Traits.Feature, Traits.Features.ExtractMethod)] + [WpfFact, Trait(Traits.Feature, Traits.Features.ExtractMethod)] public void ExtractViaCodeActionWithMoveLocal() { VisualStudio.Editor.SetText(TestSource); diff --git a/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpF1Help.cs b/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpF1Help.cs index 2bcc3f8a7c475..f0473ad1fb3c8 100644 --- a/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpF1Help.cs +++ b/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpF1Help.cs @@ -3,6 +3,7 @@ using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Test.Utilities; using Microsoft.VisualStudio.IntegrationTest.Utilities; +using Roslyn.Test.Utilities; using Xunit; namespace Roslyn.VisualStudio.IntegrationTests.CSharp @@ -17,7 +18,7 @@ public CSharpF1Help(VisualStudioInstanceFactory instanceFactory) { } - [Fact, Trait(Traits.Feature, Traits.Features.F1Help)] + [WpfFact, Trait(Traits.Feature, Traits.Features.F1Help)] void F1Help() { var text = @" diff --git a/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpFindReferences.cs b/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpFindReferences.cs index 7afb8b6368121..22d17cc5fd784 100644 --- a/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpFindReferences.cs +++ b/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpFindReferences.cs @@ -6,6 +6,7 @@ using Microsoft.VisualStudio.IntegrationTest.Utilities; using Microsoft.VisualStudio.IntegrationTest.Utilities.Common; using Microsoft.VisualStudio.IntegrationTest.Utilities.Input; +using Roslyn.Test.Utilities; using Xunit; using ProjectUtils = Microsoft.VisualStudio.IntegrationTest.Utilities.Common.ProjectUtils; @@ -21,7 +22,7 @@ public CSharpFindReferences(VisualStudioInstanceFactory instanceFactory) { } - [Fact, Trait(Traits.Feature, Traits.Features.FindReferences)] + [WpfFact, Trait(Traits.Feature, Traits.Features.FindReferences)] public void FindReferencesToCtor() { SetUpEditor(@" @@ -70,7 +71,7 @@ void M() }); } - [Fact, Trait(Traits.Feature, Traits.Features.FindReferences)] + [WpfFact, Trait(Traits.Feature, Traits.Features.FindReferences)] public void FindReferencesToLocals() { using (var telemetry = VisualStudio.EnableTestTelemetryChannel()) @@ -116,7 +117,7 @@ static void Main() } } - [Fact, Trait(Traits.Feature, Traits.Features.FindReferences)] + [WpfFact, Trait(Traits.Feature, Traits.Features.FindReferences)] public void FindReferencesToString() { SetUpEditor(@" diff --git a/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpFormatting.cs b/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpFormatting.cs index 84b1662e7826c..aea794708c654 100644 --- a/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpFormatting.cs +++ b/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpFormatting.cs @@ -5,6 +5,7 @@ using Microsoft.CodeAnalysis.Test.Utilities; using Microsoft.VisualStudio.IntegrationTest.Utilities; using Microsoft.VisualStudio.IntegrationTest.Utilities.Input; +using Roslyn.Test.Utilities; using Xunit; namespace Roslyn.VisualStudio.IntegrationTests.CSharp @@ -19,7 +20,7 @@ public CSharpFormatting(VisualStudioInstanceFactory instanceFactory) { } - [Fact, Trait(Traits.Feature, Traits.Features.Formatting)] + [WpfFact, Trait(Traits.Feature, Traits.Features.Formatting)] public void AlignOpenBraceWithMethodDeclaration() { using (var telemetry = VisualStudio.EnableTestTelemetryChannel()) @@ -44,7 +45,7 @@ void Main() } } - [Fact, Trait(Traits.Feature, Traits.Features.Formatting)] + [WpfFact, Trait(Traits.Feature, Traits.Features.Formatting)] public void FormatOnSemicolon() { SetUpEditor(@" @@ -71,7 +72,7 @@ void Goo() }"); } - [Fact, Trait(Traits.Feature, Traits.Features.Formatting)] + [WpfFact, Trait(Traits.Feature, Traits.Features.Formatting)] public void FormatSelection() { SetUpEditor(@" @@ -90,7 +91,7 @@ public void M() }"); } - [Fact, Trait(Traits.Feature, Traits.Features.Formatting)] + [WpfFact, Trait(Traits.Feature, Traits.Features.Formatting)] public void PasteCodeWithLambdaBody() { SetUpEditor(@" @@ -153,7 +154,7 @@ static void Main() }"); } - [Fact, Trait(Traits.Feature, Traits.Features.Formatting)] + [WpfFact, Trait(Traits.Feature, Traits.Features.Formatting)] public void PasteCodeWithLambdaBody2() { SetUpEditor(@" @@ -196,7 +197,7 @@ static void Main() }"); } - [Fact, Trait(Traits.Feature, Traits.Features.Formatting)] + [WpfFact, Trait(Traits.Feature, Traits.Features.Formatting)] public void PasteCodeWithLambdaBody3() { SetUpEditor(@" @@ -239,7 +240,7 @@ static void Main() }"); } - [Fact(Skip = "https://github.com/dotnet/roslyn/issues/18065"), + [WpfFact(Skip = "https://github.com/dotnet/roslyn/issues/18065"), Trait(Traits.Feature, Traits.Features.Formatting)] public void ShiftEnterWithIntelliSenseAndBraceMatching() { diff --git a/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpGenerateFromUsage.cs b/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpGenerateFromUsage.cs index b89fa3e0f102f..6e5d5221edb2c 100644 --- a/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpGenerateFromUsage.cs +++ b/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpGenerateFromUsage.cs @@ -3,6 +3,7 @@ using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Test.Utilities; using Microsoft.VisualStudio.IntegrationTest.Utilities; +using Roslyn.Test.Utilities; using Xunit; namespace Roslyn.VisualStudio.IntegrationTests.CSharp @@ -17,7 +18,7 @@ public CSharpGenerateFromUsage(VisualStudioInstanceFactory instanceFactory) { } - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateLocal)] + [WpfFact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateLocal)] public void GenerateLocal() { SetUpEditor( diff --git a/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpGenerateTypeDialog.cs b/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpGenerateTypeDialog.cs index f8803e0f31de2..d369787cefbd1 100644 --- a/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpGenerateTypeDialog.cs +++ b/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpGenerateTypeDialog.cs @@ -4,6 +4,7 @@ using Microsoft.CodeAnalysis.Test.Utilities; using Microsoft.VisualStudio.IntegrationTest.Utilities; using Microsoft.VisualStudio.IntegrationTest.Utilities.OutOfProcess; +using Roslyn.Test.Utilities; using Xunit; using ProjectUtils = Microsoft.VisualStudio.IntegrationTest.Utilities.Common.ProjectUtils; @@ -21,7 +22,7 @@ public CSharpGenerateTypeDialog(VisualStudioInstanceFactory instanceFactory) { } - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateType)] + [WpfFact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateType)] public void OpenAndCloseDialog() { SetUpEditor(@"class C @@ -42,7 +43,7 @@ void Method() GenerateTypeDialog.VerifyClosed(); } - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateType)] + [WpfFact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateType)] public void CSharpToBasic() { var vbProj = new ProjectUtils.Project("VBProj"); diff --git a/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpGoToDefinition.cs b/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpGoToDefinition.cs index efd09eedbce4e..b255da6ed9c9c 100644 --- a/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpGoToDefinition.cs +++ b/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpGoToDefinition.cs @@ -5,6 +5,7 @@ using Microsoft.CodeAnalysis.Test.Utilities; using Microsoft.VisualStudio.IntegrationTest.Utilities; using Microsoft.VisualStudio.IntegrationTest.Utilities.Common; +using Roslyn.Test.Utilities; using Xunit; using ProjectUtils = Microsoft.VisualStudio.IntegrationTest.Utilities.Common.ProjectUtils; @@ -20,7 +21,7 @@ public CSharpGoToDefinition(VisualStudioInstanceFactory instanceFactory) { } - [Fact, Trait(Traits.Feature, Traits.Features.GoToDefinition)] + [WpfFact, Trait(Traits.Feature, Traits.Features.GoToDefinition)] public void GoToClassDeclaration() { var project = new ProjectUtils.Project(ProjectName); @@ -43,7 +44,7 @@ public void GoToClassDeclaration() Assert.False(VisualStudio.Shell.IsActiveTabProvisional()); } - [Fact, Trait(Traits.Feature, Traits.Features.GoToDefinition)] + [WpfFact, Trait(Traits.Feature, Traits.Features.GoToDefinition)] public void GoToDefinitionOpensProvisionalTabIfDocumentNotAlreadyOpen() { var project = new ProjectUtils.Project(ProjectName); @@ -68,7 +69,7 @@ public void GoToDefinitionOpensProvisionalTabIfDocumentNotAlreadyOpen() Assert.True(VisualStudio.Shell.IsActiveTabProvisional()); } - [Fact, Trait(Traits.Feature, Traits.Features.GoToDefinition)] + [WpfFact, Trait(Traits.Feature, Traits.Features.GoToDefinition)] public void GoToDefinitionWithMultipleResults() { SetUpEditor( diff --git a/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpGoToImplementation.cs b/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpGoToImplementation.cs index 7996601f74331..fc52c0844209f 100644 --- a/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpGoToImplementation.cs +++ b/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpGoToImplementation.cs @@ -3,6 +3,7 @@ using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Test.Utilities; using Microsoft.VisualStudio.IntegrationTest.Utilities; +using Roslyn.Test.Utilities; using Xunit; using ProjectUtils = Microsoft.VisualStudio.IntegrationTest.Utilities.Common.ProjectUtils; @@ -18,7 +19,7 @@ public CSharpGoToImplementation(VisualStudioInstanceFactory instanceFactory) { } - [Fact, Trait(Traits.Feature, Traits.Features.GoToImplementation)] + [WpfFact, Trait(Traits.Feature, Traits.Features.GoToImplementation)] public void SimpleGoToImplementation() { var project = new ProjectUtils.Project(ProjectName); @@ -40,7 +41,7 @@ public void SimpleGoToImplementation() Assert.False(VisualStudio.Shell.IsActiveTabProvisional()); } - [Fact, Trait(Traits.Feature, Traits.Features.GoToImplementation)] + [WpfFact, Trait(Traits.Feature, Traits.Features.GoToImplementation)] public void GoToImplementationOpensProvisionalTabIfDocumentNotOpen() { var project = new ProjectUtils.Project(ProjectName); @@ -66,7 +67,7 @@ public void GoToImplementationOpensProvisionalTabIfDocumentNotOpen() // TODO: Enable this once the GoToDefinition tests are merged - [Fact, Trait(Traits.Feature, Traits.Features.GoToImplementation)] + [WpfFact, Trait(Traits.Feature, Traits.Features.GoToImplementation)] public void GoToImplementationFromMetadataAsSource() { var project = new ProjectUtils.Project(ProjectName); diff --git a/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpImmediate.cs b/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpImmediate.cs index a5b91f32a85a0..a65fecca48807 100644 --- a/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpImmediate.cs +++ b/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpImmediate.cs @@ -1,9 +1,11 @@ // Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using System.Threading.Tasks; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Shared.TestHooks; using Microsoft.VisualStudio.IntegrationTest.Utilities; using Microsoft.VisualStudio.IntegrationTest.Utilities.Input; +using Roslyn.Test.Utilities; using Xunit; using ProjectUtils = Microsoft.VisualStudio.IntegrationTest.Utilities.Common.ProjectUtils; @@ -14,15 +16,22 @@ public class CSharpImmediate : AbstractEditorTest { protected override string LanguageName => LanguageNames.CSharp; - public CSharpImmediate(VisualStudioInstanceFactory instanceFactory) : base(instanceFactory) + public CSharpImmediate(VisualStudioInstanceFactory instanceFactory) + : base(instanceFactory) { + } + + public override async Task InitializeAsync() + { + await base.InitializeAsync().ConfigureAwait(true); + VisualStudio.SolutionExplorer.CreateSolution(nameof(CSharpInteractive)); var testProj = new ProjectUtils.Project("TestProj"); VisualStudio.SolutionExplorer.AddProject(testProj, WellKnownProjectTemplates.ConsoleApplication, LanguageNames.CSharp); } - [Fact] - public void DumpLocalVaribleValue() + [WpfFact(Skip = "https://github.com/dotnet/roslyn/issues/25814")] + public void DumpLocalVariableValue() { VisualStudio.Editor.SetText(@" class Program diff --git a/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpIntelliSense.cs b/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpIntelliSense.cs index 1eca38a1588a3..0127cdc648e45 100644 --- a/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpIntelliSense.cs +++ b/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpIntelliSense.cs @@ -4,6 +4,7 @@ using Microsoft.CodeAnalysis.Test.Utilities; using Microsoft.VisualStudio.IntegrationTest.Utilities; using Microsoft.VisualStudio.IntegrationTest.Utilities.Input; +using Roslyn.Test.Utilities; using Xunit; namespace Roslyn.VisualStudio.IntegrationTests.CSharp @@ -18,7 +19,7 @@ public CSharpIntelliSense(VisualStudioInstanceFactory instanceFactory) { } - [Fact, Trait(Traits.Feature, Traits.Features.Completion)] + [WpfFact, Trait(Traits.Feature, Traits.Features.Completion)] public void AtNamespaceLevel() { SetUpEditor(@"$$"); @@ -30,7 +31,7 @@ public void AtNamespaceLevel() VisualStudio.Editor.Verify.CurrentLineText("using$$", assertCaretPosition: true); } - [Fact, Trait(Traits.Feature, Traits.Features.Completion)] + [WpfFact, Trait(Traits.Feature, Traits.Features.Completion)] public void SpeculativeTInList() { SetUpEditor(@" @@ -58,7 +59,7 @@ public T Goo() { }$$ assertCaretPosition: true); } - [Fact, Trait(Traits.Feature, Traits.Features.Completion)] + [WpfFact, Trait(Traits.Feature, Traits.Features.Completion)] public void VerifyCompletionListMembersOnStaticTypesAndCompleteThem() { SetUpEditor(@" @@ -83,7 +84,7 @@ public static void Navigate(int i){ } VisualStudio.Editor.Verify.CurrentLineText("NavigateTo.Search$$", assertCaretPosition: true); } - [Fact, Trait(Traits.Feature, Traits.Features.Completion)] + [WpfFact, Trait(Traits.Feature, Traits.Features.Completion)] public void CtrlAltSpace() { VisualStudio.Workspace.SetUseSuggestionMode(false); @@ -104,7 +105,7 @@ public void CtrlAltSpace() VisualStudio.Editor.Verify.CurrentLineText("System.Console.writeline();$$", assertCaretPosition: true); } - [Fact, Trait(Traits.Feature, Traits.Features.Completion)] + [WpfFact, Trait(Traits.Feature, Traits.Features.Completion)] public void CtrlAltSpaceOption() { VisualStudio.Workspace.SetUseSuggestionMode(false); @@ -119,7 +120,7 @@ public void CtrlAltSpaceOption() VisualStudio.Editor.Verify.CurrentLineText("nam Goo$$", assertCaretPosition: true); } - [Fact, Trait(Traits.Feature, Traits.Features.Completion)] + [WpfFact, Trait(Traits.Feature, Traits.Features.Completion)] public void CtrlSpace() { SetUpEditor("class c { void M() {$$ } }"); @@ -127,7 +128,7 @@ public void CtrlSpace() VisualStudio.Editor.Verify.CompletionItemsExist("System"); } - [Fact, Trait(Traits.Feature, Traits.Features.Completion)] + [WpfFact, Trait(Traits.Feature, Traits.Features.Completion)] public void NavigatingWithDownKey() { SetUpEditor("class c { void M() {$$ } }"); @@ -140,7 +141,7 @@ public void NavigatingWithDownKey() VisualStudio.Editor.Verify.CompletionItemsExist("char"); } - [Fact, Trait(Traits.Feature, Traits.Features.Completion)] + [WpfFact, Trait(Traits.Feature, Traits.Features.Completion)] public void XmlDocCommentIntelliSense() { SetUpEditor(@" @@ -160,7 +161,7 @@ void Main(string[] args) VisualStudio.Editor.Verify.CurrentLineText("///", assertCaretPosition: true); } - [Fact, Trait(Traits.Feature, Traits.Features.Completion)] + [WpfFact, Trait(Traits.Feature, Traits.Features.Completion)] public void XmlTagCompletion() { SetUpEditor(@" @@ -180,7 +181,7 @@ class C { } VisualStudio.Editor.Verify.CurrentLineText("/// $$", assertCaretPosition: true); } - [Fact, Trait(Traits.Feature, Traits.Features.Completion)] + [WpfFact, Trait(Traits.Feature, Traits.Features.Completion)] public void SignatureHelpShowsUp() { SetUpEditor(@" @@ -200,7 +201,7 @@ void Main(string[] args) VisualStudio.Editor.Verify.CurrentParameter("args", ""); } - [Fact, Trait(Traits.Feature, Traits.Features.Completion)] + [WpfFact, Trait(Traits.Feature, Traits.Features.Completion)] public void CompletionUsesTrackingPointsInTheFaceOfAutomaticBraceCompletion() { SetUpEditor(@" @@ -231,7 +232,7 @@ void Main(string[] args) assertCaretPosition: true); } - [Fact, Trait(Traits.Feature, Traits.Features.Completion)] + [WpfFact, Trait(Traits.Feature, Traits.Features.Completion)] public void CommitOnShiftEnter() { SetUpEditor(@" @@ -260,7 +261,7 @@ void Main(string[] args) assertCaretPosition: true); } - [Fact, Trait(Traits.Feature, Traits.Features.Completion)] + [WpfFact, Trait(Traits.Feature, Traits.Features.Completion)] public void CommitOnLeftCurly() { SetUpEditor(@" @@ -281,7 +282,7 @@ int P { get { $$} } assertCaretPosition: true); } - [Fact, Trait(Traits.Feature, Traits.Features.Completion)] + [WpfFact, Trait(Traits.Feature, Traits.Features.Completion)] public void EnsureTheCaretIsVisibleAfterALongEdit() { SetUpEditor(@" @@ -303,7 +304,7 @@ static void Main(string[] args) Assert.True(VisualStudio.Editor.IsCaretOnScreen()); } - [Fact, Trait(Traits.Feature, Traits.Features.Completion)] + [WpfFact, Trait(Traits.Feature, Traits.Features.Completion)] public void DismissOnSelect() { SetUpEditor(@"$$"); diff --git a/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpInteractive.cs b/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpInteractive.cs index 071646331262b..b70466852bc80 100644 --- a/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpInteractive.cs +++ b/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpInteractive.cs @@ -3,6 +3,7 @@ using System; using System.Threading.Tasks; using Microsoft.VisualStudio.IntegrationTest.Utilities; +using Roslyn.Test.Utilities; using Xunit; namespace Roslyn.VisualStudio.IntegrationTests.CSharp @@ -15,35 +16,35 @@ public CSharpInteractive(VisualStudioInstanceFactory instanceFactory) { } - [Fact] + [WpfFact] public void BclMathCall() { VisualStudio.InteractiveWindow.SubmitText("Math.Sin(1)"); VisualStudio.InteractiveWindow.WaitForLastReplOutput("0.8414709848078965"); } - [Fact] + [WpfFact] public void BclConsoleCall() { VisualStudio.InteractiveWindow.SubmitText(@"Console.WriteLine(""Hello, World!"");"); VisualStudio.InteractiveWindow.WaitForLastReplOutput("Hello, World!"); } - [Fact] + [WpfFact] public void ForStatement() { VisualStudio.InteractiveWindow.SubmitText("for (int i = 0; i < 10; i++) Console.WriteLine(i * i);"); VisualStudio.InteractiveWindow.WaitForLastReplOutputContains($"{81}"); } - [Fact] + [WpfFact] public void ForEachStatement() { VisualStudio.InteractiveWindow.SubmitText(@"foreach (var f in System.IO.Directory.GetFiles(@""c:\windows"")) Console.WriteLine($""{f}"".ToLower());"); VisualStudio.InteractiveWindow.WaitForLastReplOutputContains(@"c:\windows\win.ini"); } - [Fact] + [WpfFact] public void TopLevelMethod() { VisualStudio.InteractiveWindow.SubmitText(@"int Fac(int x) @@ -54,7 +55,7 @@ public void TopLevelMethod() VisualStudio.InteractiveWindow.WaitForLastReplOutput($"{24}"); } - [Fact] + [WpfFact] public async Task WpfInteractionAsync() { VisualStudio.InteractiveWindow.SubmitText(@"#r ""WindowsBase"" @@ -93,7 +94,7 @@ public async Task WpfInteractionAsync() VisualStudio.InteractiveWindow.SubmitText("b = null; w.Close(); w = null;"); } - [Fact] + [WpfFact] public void TypingHelpDirectiveWorks() { VisualStudio.Workspace.SetUseSuggestionMode(true); diff --git a/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpInteractiveAsyncOutput.cs b/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpInteractiveAsyncOutput.cs index ffc2b1d77fbad..ba22e00fb80cb 100644 --- a/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpInteractiveAsyncOutput.cs +++ b/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpInteractiveAsyncOutput.cs @@ -1,6 +1,7 @@ // Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using Microsoft.VisualStudio.IntegrationTest.Utilities; +using Roslyn.Test.Utilities; using Xunit; namespace Roslyn.VisualStudio.IntegrationTests.CSharp @@ -13,7 +14,7 @@ public CSharpInteractiveAsyncOutput(VisualStudioInstanceFactory instanceFactory) { } - [Fact] + [WpfFact] public void VerifyPreviousAndNextHistory() { VisualStudio.InteractiveWindow.SubmitText(@"#cls"); diff --git a/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpInteractiveBoxSelection.cs b/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpInteractiveBoxSelection.cs index f721246809d08..ed49e5a9c69ce 100644 --- a/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpInteractiveBoxSelection.cs +++ b/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpInteractiveBoxSelection.cs @@ -1,7 +1,9 @@ // Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using System.Threading.Tasks; using Microsoft.VisualStudio.IntegrationTest.Utilities; using Microsoft.VisualStudio.IntegrationTest.Utilities.Input; +using Roslyn.Test.Utilities; using Xunit; namespace Roslyn.VisualStudio.IntegrationTests.CSharp @@ -12,6 +14,11 @@ public class CSharpInteractiveBoxSelection : AbstractInteractiveWindowTest public CSharpInteractiveBoxSelection(VisualStudioInstanceFactory instanceFactory) : base(instanceFactory) { + } + + public override async Task InitializeAsync() + { + await base.InitializeAsync().ConfigureAwait(true); VisualStudio.InteractiveWindow.SubmitText("#cls"); } @@ -25,7 +32,7 @@ protected override void Dispose(bool disposing) base.Dispose(disposing); } - [Fact] + [WpfFact] public void TopLeftBottomRightPromptToSymbol() { InsertInputWithXAtLeft(); @@ -44,7 +51,7 @@ public void TopLeftBottomRightPromptToSymbol() 1234567890ABCDEF"); } - [Fact] + [WpfFact] public void BottomRightTopLeftPromptToSymbol() { InsertInputWithXAtLeft(); @@ -62,7 +69,7 @@ public void BottomRightTopLeftPromptToSymbol() 1234567890ABCDEF"); } - [Fact] + [WpfFact] public void TopRightBottomLeftPromptToSymbol() { InsertInputWithXAtLeft(); @@ -80,7 +87,7 @@ public void TopRightBottomLeftPromptToSymbol() 1234567890ABCDEF"); } - [Fact] + [WpfFact] public void BottomLeftTopRightPromptToSymbol() { InsertInputWithXAtLeft(); @@ -98,7 +105,7 @@ public void BottomLeftTopRightPromptToSymbol() 1234567890ABCDEF"); } - [Fact] + [WpfFact] public void TopLeftBottomRightSymbolToSymbol() { InsertInputWithSAndEAtLeft(); @@ -116,7 +123,7 @@ public void TopLeftBottomRightSymbolToSymbol() 1234567890ABCDEF"); } - [Fact] + [WpfFact] public void BottomRightTopLeftSymbolToSymbol() { InsertInputWithSAndEAtLeft(); @@ -134,7 +141,7 @@ public void BottomRightTopLeftSymbolToSymbol() 1234567890ABCDEF"); } - [Fact] + [WpfFact] public void TopRightBottomLeftSymbolToSymbol() { InsertInputWithSAndEAtLeft(); @@ -153,7 +160,7 @@ public void TopRightBottomLeftSymbolToSymbol() } - [Fact] + [WpfFact] public void BottomLeftTopRightSymbolToSymbol() { InsertInputWithSAndEAtLeft(); @@ -171,7 +178,7 @@ public void BottomLeftTopRightSymbolToSymbol() 1234567890ABCDEF"); } - [Fact] + [WpfFact] public void TopLeftBottomRightSelection1() { InsertInputWithSAndEAtLeft(); @@ -189,7 +196,7 @@ public void TopLeftBottomRightSelection1() 1234567890ABCDEF"); } - [Fact] + [WpfFact] public void TopLeftBottomRightSelection2() { InsertInputWithSAndEAtLeft(); @@ -200,7 +207,7 @@ public void TopLeftBottomRightSelection2() VerifyOriginalCodeWithSAndEAtLeft(); } - [Fact] + [WpfFact] public void TopRightBottomLeftSelection() { InsertInputWithSAndEAtLeft(); @@ -211,7 +218,7 @@ public void TopRightBottomLeftSelection() VerifyOriginalCodeWithSAndEAtLeft(); } - [Fact] + [WpfFact] public void BottomLeftTopRightSelection() { InsertInputWithSAndEAtLeft(); @@ -222,7 +229,7 @@ public void BottomLeftTopRightSelection() VerifyOriginalCodeWithSAndEAtLeft(); } - [Fact] + [WpfFact] public void SelectionTouchingSubmissionBuffer() { InsertInputWithSAndEAtLeft(); @@ -240,7 +247,7 @@ public void SelectionTouchingSubmissionBuffer() 1234567890ABCDEF"); } - [Fact] + [WpfFact] public void PrimaryPromptLongerThanSecondaryZeroWidthNextToPromptSelection() { InsertInputWithSAndEAtLeft(); @@ -258,7 +265,7 @@ public void PrimaryPromptLongerThanSecondaryZeroWidthNextToPromptSelection() 1234567890ABCDEF"); } - [Fact] + [WpfFact] public void Backspace() { InsertInputWithSAndEInTheMiddle(); @@ -276,7 +283,7 @@ public void Backspace() 1234567890ABCDEF"); } - [Fact] + [WpfFact] public void BackspaceBehavesLikeDelete() { InsertInputWithEInTheMiddle(); @@ -294,7 +301,7 @@ public void BackspaceBehavesLikeDelete() 1234567890ABCDEF"); } - [Fact] + [WpfFact] public void LeftToRightReversedBackspace() { VisualStudio.InteractiveWindow.InsertCode("1234567890ABCDEF"); @@ -305,7 +312,7 @@ public void LeftToRightReversedBackspace() VisualStudio.InteractiveWindow.Verify.LastReplInput(@"7890ABCDEF"); } - [Fact] + [WpfFact] public void LeftToRightReversedDelete() { VisualStudio.InteractiveWindow.InsertCode("1234567890ABCDEF"); @@ -316,7 +323,7 @@ public void LeftToRightReversedDelete() VisualStudio.InteractiveWindow.Verify.LastReplInput(@"4567890ABCDEF"); } - [Fact] + [WpfFact] public void LeftToRightReversedTypeCharacter() { VisualStudio.InteractiveWindow.InsertCode("1234567890ABCDEF"); diff --git a/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpInteractiveCommands.cs b/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpInteractiveCommands.cs index 7ffa46f112f8e..6210dc2f23772 100644 --- a/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpInteractiveCommands.cs +++ b/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpInteractiveCommands.cs @@ -2,6 +2,7 @@ using Microsoft.VisualStudio.IntegrationTest.Utilities; using Microsoft.VisualStudio.IntegrationTest.Utilities.Input; +using Roslyn.Test.Utilities; using Xunit; namespace Roslyn.VisualStudio.IntegrationTests.CSharp @@ -14,7 +15,7 @@ public CSharpInteractiveCommands(VisualStudioInstanceFactory instanceFactory) { } - [Fact] + [WpfFact] public void VerifyPreviousAndNextHistory() { VisualStudio.InteractiveWindow.SubmitText("1 + 2"); @@ -36,7 +37,7 @@ public void VerifyPreviousAndNextHistory() VisualStudio.InteractiveWindow.WaitForLastReplOutput("\"1\""); } - [Fact] + [WpfFact] public void VerifyMaybeExecuteInput() { VisualStudio.InteractiveWindow.InsertCode("2 + 3"); @@ -44,7 +45,7 @@ public void VerifyMaybeExecuteInput() VisualStudio.InteractiveWindow.WaitForLastReplOutput("5"); } - [Fact] + [WpfFact] public void VerifyNewLineAndIndent() { VisualStudio.InteractiveWindow.InsertCode("3 + "); @@ -54,14 +55,14 @@ public void VerifyNewLineAndIndent() VisualStudio.InteractiveWindow.WaitForLastReplOutput("7"); } - [Fact] + [WpfFact] public void VerifyExecuteInput() { VisualStudio.InteractiveWindow.SubmitText("1 + "); VisualStudio.InteractiveWindow.WaitForLastReplOutputContains("CS1733"); } - [Fact] + [WpfFact] public void VerifyForceNewLineAndIndent() { VisualStudio.InteractiveWindow.InsertCode("1 + 2"); @@ -71,7 +72,7 @@ public void VerifyForceNewLineAndIndent() VisualStudio.InteractiveWindow.Verify.ReplPromptConsistency("", "6"); } - [Fact] + [WpfFact] public void VerifyCancelInput() { VisualStudio.InteractiveWindow.InsertCode("1 + 4"); @@ -80,7 +81,7 @@ public void VerifyCancelInput() VisualStudio.InteractiveWindow.Verify.LastReplInput(string.Empty); } - [Fact] + [WpfFact] public void VerifyUndoAndRedo() { VisualStudio.InteractiveWindow.ClearReplText(); @@ -93,7 +94,7 @@ public void VerifyUndoAndRedo() VisualStudio.InteractiveWindow.WaitForLastReplOutput("6"); } - [Fact] + [WpfFact] public void CutDeletePasteSelectAll() { ClearInteractiveWindow(); @@ -130,7 +131,7 @@ public void CutDeletePasteSelectAll() // of these tests and convert them to unit-tests. // --> //