From fa9b762ad798c48fab867639164fbe9debd7020c Mon Sep 17 00:00:00 2001 From: Michael Simons Date: Tue, 15 Jul 2025 08:24:04 -0500 Subject: [PATCH 01/18] Add source build ci leg covering system libs (#1453) --- build.sh | 9 +++++++-- eng/pipelines/templates/jobs/vmr-build.yml | 13 ++++++++++++- .../templates/stages/source-build-and-validate.yml | 1 + .../templates/stages/source-build-stages.yml | 13 +++++++++++++ repo-projects/runtime.proj | 9 ++++----- 5 files changed, 37 insertions(+), 8 deletions(-) diff --git a/build.sh b/build.sh index a287a8b7659..b072656330f 100755 --- a/build.sh +++ b/build.sh @@ -17,7 +17,7 @@ echo " --binaryLog Create MSBuild binary log (short: -b echo " --arch, --target-arch Target architecture: e.g. x64, x86, arm64, arm, riscv64" echo " --branding Specify versioning for shipping packages/assets. 'preview' will produce assets suffixed with '.final', 'rtm' will not contain a pre-release suffix. Default or unspecified will use VMR repo defaults." echo " --verbosity Msbuild verbosity: q[uiet], m[inimal], n[ormal], d[etailed], and diag[nostic] (short: -v)" - echo " --with-system-libs Use system versions of these libraries. Combine with a plus. eg brotli+libunwind+rapidjson+zlib" + echo " --with-system-libs Use system versions of these libraries. Combine with a plus. 'all' will use all supported libraries. e.g. brotli+libunwind+rapidjson+zlib" echo "" echo "Actions:" @@ -138,7 +138,12 @@ while [[ $# > 0 ]]; do shift ;; -with-system-libs) - properties+=( "/p:UseSystemLibs=$2" ) + value="$2" + if [[ "$value" != +* ]]; then + # Ensure the value is prepended with a '+' + value="+$value" + fi + properties+=( "/p:UseSystemLibs=$value" ) shift ;; -verbosity|-v) diff --git a/eng/pipelines/templates/jobs/vmr-build.yml b/eng/pipelines/templates/jobs/vmr-build.yml index fe6a2f9d153..6066e4262bb 100644 --- a/eng/pipelines/templates/jobs/vmr-build.yml +++ b/eng/pipelines/templates/jobs/vmr-build.yml @@ -69,6 +69,11 @@ parameters: type: object default: '' +# Enables usage of the system libraries when building. +- name: useSystemLibraries + type: boolean + default: false + #### SOURCE-ONLY parameters #### # Instead of building the VMR directly, exports the sources into a tarball and builds from that @@ -227,8 +232,14 @@ jobs: - name: brandingArgument value: $(commandPrefix)branding $(brandingType) + - name: useSystemLibrariesArgument + ${{ if eq(parameters.useSystemLibraries, 'true') }}: + value: $(commandPrefix)with-system-libs all + ${{ else }}: + value: '' + - name: baseArguments - value: $(commandPrefix)ci $(cleanArgument) $(commandPrefix)prepareMachine -c ${{ parameters.configuration }} $(brandingArgument) + value: $(commandPrefix)ci $(cleanArgument) $(commandPrefix)prepareMachine -c ${{ parameters.configuration }} $(brandingArgument) $(useSystemLibrariesArgument) - name: baseProperties value: $(officialBuildProperties) /p:VerticalName=$(Agent.JobName) diff --git a/eng/pipelines/templates/stages/source-build-and-validate.yml b/eng/pipelines/templates/stages/source-build-and-validate.yml index 5e37a59fff9..1a7b2804d36 100644 --- a/eng/pipelines/templates/stages/source-build-and-validate.yml +++ b/eng/pipelines/templates/stages/source-build-and-validate.yml @@ -101,6 +101,7 @@ stages: buildFromArchive: ${{ leg.buildFromArchive }} runOnline: ${{ leg.runOnline }} useMonoRuntime: ${{ leg.useMonoRuntime }} + useSystemLibraries: ${{ leg.useSystemLibraries }} withPreviousSDK: ${{ leg.withPreviousSDK }} # We only want to publish SB artifacts for each distinct distro/version/arch combination diff --git a/eng/pipelines/templates/stages/source-build-stages.yml b/eng/pipelines/templates/stages/source-build-stages.yml index a2c059ab5c0..b359f462c42 100644 --- a/eng/pipelines/templates/stages/source-build-stages.yml +++ b/eng/pipelines/templates/stages/source-build-stages.yml @@ -63,6 +63,7 @@ stages: enablePoison: false # 🚫 runOnline: true # ✅ useMonoRuntime: false # 🚫 + useSystemLibraries: false # 🚫 withPreviousSDK: false # 🚫 - ${{ if containsValue(parameters.verifications, 'source-build-stage2') }}: @@ -74,6 +75,7 @@ stages: enablePoison: false # 🚫 runOnline: false # 🚫 useMonoRuntime: false # 🚫 + useSystemLibraries: false # 🚫 withPreviousSDK: false # 🚫 reuseBuildArtifactsFrom: '{0}_Online_MsftSdk_x64' @@ -88,6 +90,7 @@ stages: excludeOmniSharpTests: false # 🚫 runOnline: false # 🚫 useMonoRuntime: false # 🚫 + useSystemLibraries: false # 🚫 withPreviousSDK: false # 🚫 - buildNameFormat: '{0}_Offline_PreviousSourceBuiltSdk' @@ -97,6 +100,7 @@ stages: enablePoison: true # ✅ runOnline: false # 🚫 useMonoRuntime: false # 🚫 + useSystemLibraries: false # 🚫 withPreviousSDK: true # ✅ - buildNameFormat: '{0}_Offline_MsftSdk' @@ -106,6 +110,7 @@ stages: enablePoison: false # 🚫 runOnline: false # 🚫 useMonoRuntime: false # 🚫 + useSystemLibraries: false # 🚫 withPreviousSDK: false # 🚫 - buildNameFormat: '{0}_Offline_MsftSdk' @@ -115,6 +120,7 @@ stages: enablePoison: false # 🚫 runOnline: false # 🚫 useMonoRuntime: false # 🚫 + useSystemLibraries: false # 🚫 withPreviousSDK: false # 🚫 - buildNameFormat: '{0}_Offline_MsftSdk' @@ -124,6 +130,7 @@ stages: enablePoison: false # 🚫 runOnline: false # 🚫 useMonoRuntime: false # 🚫 + useSystemLibraries: false # 🚫 withPreviousSDK: false # 🚫 - buildNameFormat: '{0}_Online_PreviousSourceBuiltSdk' @@ -133,6 +140,7 @@ stages: enablePoison: false # 🚫 runOnline: true # ✅ useMonoRuntime: false # 🚫 + useSystemLibraries: false # 🚫 withPreviousSDK: true # ✅ - buildNameFormat: '{0}_Mono_Offline_MsftSdk' @@ -142,6 +150,7 @@ stages: enablePoison: false # 🚫 runOnline: false # 🚫 useMonoRuntime: true # ✅ + useSystemLibraries: false # 🚫 withPreviousSDK: false # 🚫 - buildNameFormat: '{0}_Offline_MsftSdk' @@ -151,6 +160,7 @@ stages: enablePoison: false # 🚫 runOnline: false # 🚫 useMonoRuntime: false # 🚫 + useSystemLibraries: true # ✅ withPreviousSDK: false # 🚫 - buildNameFormat: '{0}Arm64_Offline_MsftSdk' @@ -160,6 +170,7 @@ stages: enablePoison: false # 🚫 runOnline: false # 🚫 useMonoRuntime: false # 🚫 + useSystemLibraries: false # 🚫 withPreviousSDK: false # 🚫 - buildNameFormat: '{0}_Offline_CurrentSourceBuiltSdk' @@ -169,6 +180,7 @@ stages: enablePoison: false # 🚫 runOnline: false # 🚫 useMonoRuntime: false # 🚫 + useSystemLibraries: false # 🚫 withPreviousSDK: false # 🚫 reuseBuildArtifactsFrom: '{0}_Offline_MsftSdk_x64' @@ -179,5 +191,6 @@ stages: enablePoison: false # 🚫 runOnline: false # 🚫 useMonoRuntime: true # ✅ + useSystemLibraries: false # 🚫 withPreviousSDK: false # 🚫 reuseBuildArtifactsFrom: '{0}_Mono_Offline_MsftSdk_x64' diff --git a/repo-projects/runtime.proj b/repo-projects/runtime.proj index b313f64fb17..38c563e4322 100644 --- a/repo-projects/runtime.proj +++ b/repo-projects/runtime.proj @@ -46,13 +46,12 @@ $(BuildArgs) $(FlagParameterPrefix)pgoinstrument - +$(UseSystemLibs) - $(BuildArgs) --cmakeargs -DCLR_CMAKE_USE_SYSTEM_BROTLI=true - $(BuildArgs) --cmakeargs -DCLR_CMAKE_USE_SYSTEM_LIBUNWIND=true + $(BuildArgs) --cmakeargs -DCLR_CMAKE_USE_SYSTEM_BROTLI=true + $(BuildArgs) --cmakeargs -DCLR_CMAKE_USE_SYSTEM_LIBUNWIND=true - $(BuildArgs) --cmakeargs -DCLR_CMAKE_USE_SYSTEM_RAPIDJSON=true - $(BuildArgs) --cmakeargs -DCLR_CMAKE_USE_SYSTEM_ZLIB=true + $(BuildArgs) --cmakeargs -DCLR_CMAKE_USE_SYSTEM_RAPIDJSON=true + $(BuildArgs) --cmakeargs -DCLR_CMAKE_USE_SYSTEM_ZLIB=true $(BuildArgs) /p:FeatureXplatEventSource=false From a66e9ad30c8ebd6353782f5ae947a4f9e7eeb5ab Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Tue, 15 Jul 2025 07:16:25 -0700 Subject: [PATCH 02/18] [main] Source code updates from dotnet/roslyn (#1489) Co-authored-by: dotnet-maestro[bot] --- ...saryNullableDirectiveDiagnosticAnalyzer.cs | 23 +- .../NullableImpactingSpanWalker.cs | 4 + .../AddObsoleteAttributeTests.cs | 10 +- .../Tests/FileHeaders/FileHeaderTests.cs | 9 +- .../RemoveUnnecessaryCastTests.cs | 24 + ...RemoveUnnecessaryNullableDirectiveTests.cs | 27 + ...veUnnecessaryAttributeSuppressionsTests.cs | 8 +- .../UpdateLegacySuppressionsTests.cs | 9 +- .../UseImplicitTypeTests.cs | 48 +- .../RemoveUnnecessaryParenthesesTests.vb | 11 +- ...dMissingImportsRefactoringProviderTests.cs | 41 +- .../AddUsing/AbstractAddUsingTests.cs | 14 +- .../CodeActions/AddUsing/AddUsingTests.cs | 13 + ...ateEqualsAndGetHashCodeFromMembersTests.cs | 10 +- .../GenerateType/GenerateTypeTests.cs | 22 + ...berFromPrimaryConstructorParameterTests.cs | 44 + .../CSharpMoveStaticMembersTests.cs | 7 +- ...agnosticProviderBasedUserDiagnosticTest.cs | 47 +- .../Core/InlineRename/InlineRenameSession.cs | 9 +- .../UI/Adornment/RenameFlyoutViewModel.cs | 5 +- .../CaretPreservingEditTransaction.cs | 5 +- ...Presenter.SignatureHelpPresenterSession.cs | 5 +- .../CodeActions/AbstractCodeActionTest.cs | 5 +- .../FindReferencesTests.NamedTypeSymbols.vb | 60 + ...tructorParameterCodeRefactoringProvider.cs | 34 +- .../GenerateComparisonOperatorsTests.cs | 6 +- .../GenerateOverridesWithDialogCodeAction.cs | 5 +- .../AbstractGenerateTypeService.cs | 3 +- .../Portable/QuickInfo/QuickInfoUtilities.cs | 5 +- ...pertyWithMethodsCodeRefactoringProvider.cs | 16 +- .../AbstractCodeActionTest_NoEditor.cs | 5 +- .../ReplacePropertyWithMethodsTests.vb | 21 +- .../ResxGeneratorTests.cs | 1490 ++++++++--------- ...oidAllocationWithArrayEmptyCodeFixTests.cs | 802 ++++----- ...CallSiteImplicitAllocationAnalyzerTests.cs | 293 ++-- .../ConcatenationAllocationAnalyzerTests.cs | 163 +- .../DisplayClassAllocationAnalyzerTests.cs | 236 +-- .../EnumeratorAllocationAnalyzerTests.cs | 245 +-- .../ExplicitAllocationAnalyzerTests.cs | 1322 +++++++-------- .../TypeConversionAllocationAnalyzerTests.cs | 1232 +++++++------- .../src/Scripting/Core/ScriptBuilder.cs | 5 +- .../InheritanceMarginLogger.cs | 5 +- .../Core/Def/Utilities/TaskItemsEnum.cs | 5 +- .../AnalyzersCommandHandler.cs | 10 +- .../CSharp/CSharpAddMissingUsingsOnPaste.cs | 7 +- .../Finders/AbstractReferenceFinder.cs | 24 +- .../Services/SyntaxFacts/CSharpSyntaxKinds.cs | 2 + .../Simplifiers/CastSimplifier.cs | 2 +- .../TypeStyle/CSharpUseImplicitTypeHelper.cs | 18 +- .../Core/Extensions/SymbolUsageInfo.cs | 28 +- .../Core/Services/SyntaxFacts/ISyntaxKinds.cs | 2 + ...ParenthesizedExpressionSyntaxExtensions.vb | 2 + .../SyntaxFacts/VisualBasicSyntaxKinds.vb | 2 + .../CSharpCodeGenerationHelpers.cs | 5 +- .../CodeGeneration/NamedTypeGenerator.cs | 6 +- .../CodeGeneration/CodeGenerationHelpers.cs | 9 +- src/source-manifest.json | 4 +- 57 files changed, 3381 insertions(+), 3093 deletions(-) diff --git a/src/roslyn/src/Analyzers/CSharp/Analyzers/RemoveUnnecessaryNullableDirective/CSharpRemoveUnnecessaryNullableDirectiveDiagnosticAnalyzer.cs b/src/roslyn/src/Analyzers/CSharp/Analyzers/RemoveUnnecessaryNullableDirective/CSharpRemoveUnnecessaryNullableDirectiveDiagnosticAnalyzer.cs index d1c1f8c4445..544731492af 100644 --- a/src/roslyn/src/Analyzers/CSharp/Analyzers/RemoveUnnecessaryNullableDirective/CSharpRemoveUnnecessaryNullableDirectiveDiagnosticAnalyzer.cs +++ b/src/roslyn/src/Analyzers/CSharp/Analyzers/RemoveUnnecessaryNullableDirective/CSharpRemoveUnnecessaryNullableDirectiveDiagnosticAnalyzer.cs @@ -19,26 +19,19 @@ namespace Microsoft.CodeAnalysis.RemoveUnnecessaryNullableDirective; [DiagnosticAnalyzer(LanguageNames.CSharp)] -internal sealed class CSharpRemoveUnnecessaryNullableDirectiveDiagnosticAnalyzer - : AbstractBuiltInUnnecessaryCodeStyleDiagnosticAnalyzer +internal sealed class CSharpRemoveUnnecessaryNullableDirectiveDiagnosticAnalyzer() + : AbstractBuiltInUnnecessaryCodeStyleDiagnosticAnalyzer(IDEDiagnosticIds.RemoveUnnecessaryNullableDirectiveDiagnosticId, + EnforceOnBuildValues.RemoveUnnecessaryNullableDirective, + option: null, + fadingOption: null, + new LocalizableResourceString(nameof(CSharpAnalyzersResources.Remove_unnecessary_nullable_directive), CSharpAnalyzersResources.ResourceManager, typeof(CSharpAnalyzersResources)), + new LocalizableResourceString(nameof(CSharpAnalyzersResources.Nullable_directive_is_unnecessary), CSharpAnalyzersResources.ResourceManager, typeof(CSharpAnalyzersResources))) { - public CSharpRemoveUnnecessaryNullableDirectiveDiagnosticAnalyzer() - : base(IDEDiagnosticIds.RemoveUnnecessaryNullableDirectiveDiagnosticId, - EnforceOnBuildValues.RemoveUnnecessaryNullableDirective, - option: null, - fadingOption: null, - new LocalizableResourceString(nameof(CSharpAnalyzersResources.Remove_unnecessary_nullable_directive), CSharpAnalyzersResources.ResourceManager, typeof(CSharpAnalyzersResources)), - new LocalizableResourceString(nameof(CSharpAnalyzersResources.Nullable_directive_is_unnecessary), CSharpAnalyzersResources.ResourceManager, typeof(CSharpAnalyzersResources))) - { - } - public override DiagnosticAnalyzerCategory GetAnalyzerCategory() => DiagnosticAnalyzerCategory.SemanticDocumentAnalysis; protected override void InitializeWorker(AnalysisContext context) - { - context.RegisterCompilationStartAction(AnalyzeCompilation); - } + => context.RegisterCompilationStartAction(AnalyzeCompilation); private void AnalyzeCompilation(CompilationStartAnalysisContext context) { diff --git a/src/roslyn/src/Analyzers/CSharp/Analyzers/RemoveUnnecessaryNullableDirective/NullableImpactingSpanWalker.cs b/src/roslyn/src/Analyzers/CSharp/Analyzers/RemoveUnnecessaryNullableDirective/NullableImpactingSpanWalker.cs index 38622e35bf7..372636faed9 100644 --- a/src/roslyn/src/Analyzers/CSharp/Analyzers/RemoveUnnecessaryNullableDirective/NullableImpactingSpanWalker.cs +++ b/src/roslyn/src/Analyzers/CSharp/Analyzers/RemoveUnnecessaryNullableDirective/NullableImpactingSpanWalker.cs @@ -97,6 +97,10 @@ private static bool IsLanguageRestrictedToNonNullForm(TypeSyntax node) return true; } + // An attribute name cannot itself be nullable. `[CLSCompliant?]` is not a thing. + if (node.IsParentKind(SyntaxKind.Attribute)) + return true; + return false; // If this is Y in X.Y, walk up to X.Y diff --git a/src/roslyn/src/Analyzers/CSharp/Tests/AddObsoleteAttribute/AddObsoleteAttributeTests.cs b/src/roslyn/src/Analyzers/CSharp/Tests/AddObsoleteAttribute/AddObsoleteAttributeTests.cs index 8d60be340f0..a940ac5dcca 100644 --- a/src/roslyn/src/Analyzers/CSharp/Tests/AddObsoleteAttribute/AddObsoleteAttributeTests.cs +++ b/src/roslyn/src/Analyzers/CSharp/Tests/AddObsoleteAttribute/AddObsoleteAttributeTests.cs @@ -3,14 +3,18 @@ // See the LICENSE file in the project root for more information. using System.Threading.Tasks; +using Microsoft.CodeAnalysis.CSharp.AddObsoleteAttribute; +using Microsoft.CodeAnalysis.Editor.UnitTests.CodeActions; using Microsoft.CodeAnalysis.Test.Utilities; +using Microsoft.CodeAnalysis.Testing; using Xunit; -using VerifyCS = Microsoft.CodeAnalysis.Editor.UnitTests.CodeActions.CSharpCodeFixVerifier< - Microsoft.CodeAnalysis.Testing.EmptyDiagnosticAnalyzer, - Microsoft.CodeAnalysis.CSharp.AddObsoleteAttribute.CSharpAddObsoleteAttributeCodeFixProvider>; namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.AddObsoleteAttribute; +using VerifyCS = CSharpCodeFixVerifier< + EmptyDiagnosticAnalyzer, + CSharpAddObsoleteAttributeCodeFixProvider>; + [Trait(Traits.Feature, Traits.Features.CodeActionsAddObsoleteAttribute)] public sealed class AddObsoleteAttributeTests { diff --git a/src/roslyn/src/Analyzers/CSharp/Tests/FileHeaders/FileHeaderTests.cs b/src/roslyn/src/Analyzers/CSharp/Tests/FileHeaders/FileHeaderTests.cs index 4a8b37d756b..2bc54c7c094 100644 --- a/src/roslyn/src/Analyzers/CSharp/Tests/FileHeaders/FileHeaderTests.cs +++ b/src/roslyn/src/Analyzers/CSharp/Tests/FileHeaders/FileHeaderTests.cs @@ -3,16 +3,19 @@ // See the LICENSE file in the project root for more information. using System.Threading.Tasks; +using Microsoft.CodeAnalysis.CSharp.FileHeaders; +using Microsoft.CodeAnalysis.Editor.UnitTests.CodeActions; using Microsoft.CodeAnalysis.Formatting; using Microsoft.CodeAnalysis.Testing; using Roslyn.Test.Utilities; using Xunit; -using VerifyCS = Microsoft.CodeAnalysis.Editor.UnitTests.CodeActions.CSharpCodeFixVerifier< - Microsoft.CodeAnalysis.CSharp.FileHeaders.CSharpFileHeaderDiagnosticAnalyzer, - Microsoft.CodeAnalysis.CSharp.FileHeaders.CSharpFileHeaderCodeFixProvider>; namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.FileHeaders; +using VerifyCS = CSharpCodeFixVerifier< + CSharpFileHeaderDiagnosticAnalyzer, + CSharpFileHeaderCodeFixProvider>; + public sealed class FileHeaderTests { private const string TestSettings = """ diff --git a/src/roslyn/src/Analyzers/CSharp/Tests/RemoveUnnecessaryCast/RemoveUnnecessaryCastTests.cs b/src/roslyn/src/Analyzers/CSharp/Tests/RemoveUnnecessaryCast/RemoveUnnecessaryCastTests.cs index 05cb84877df..9047d5010c8 100644 --- a/src/roslyn/src/Analyzers/CSharp/Tests/RemoveUnnecessaryCast/RemoveUnnecessaryCastTests.cs +++ b/src/roslyn/src/Analyzers/CSharp/Tests/RemoveUnnecessaryCast/RemoveUnnecessaryCastTests.cs @@ -13484,4 +13484,28 @@ uint M(bool condition) CodeFixTestBehaviors = CodeFixTestBehaviors.FixOne | CodeFixTestBehaviors.SkipFixAllCheck, DiagnosticSelector = d => d[1], }.RunAsync(); + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/60720")] + public Task TestNullableWithinGeneric() + => new VerifyCS.Test + { + TestCode = """ + #nullable enable + + using System; + using System.Threading.Tasks; + + Task M(string s, Func> func) + { + return string.IsNullOrWhiteSpace(s) + ? Task.FromResult(null) + : (Task)func(s)!; + } + """, + LanguageVersion = LanguageVersion.CSharp13, + TestState = + { + OutputKind = OutputKind.ConsoleApplication, + }, + }.RunAsync(); } diff --git a/src/roslyn/src/Analyzers/CSharp/Tests/RemoveUnnecessaryNullableDirective/CSharpRemoveUnnecessaryNullableDirectiveTests.cs b/src/roslyn/src/Analyzers/CSharp/Tests/RemoveUnnecessaryNullableDirective/CSharpRemoveUnnecessaryNullableDirectiveTests.cs index f4ffe53ba2e..b9656bbb560 100644 --- a/src/roslyn/src/Analyzers/CSharp/Tests/RemoveUnnecessaryNullableDirective/CSharpRemoveUnnecessaryNullableDirectiveTests.cs +++ b/src/roslyn/src/Analyzers/CSharp/Tests/RemoveUnnecessaryNullableDirective/CSharpRemoveUnnecessaryNullableDirectiveTests.cs @@ -8,6 +8,7 @@ using Microsoft.CodeAnalysis.RemoveUnnecessaryNullableDirective; using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.Test.Utilities; +using Roslyn.Test.Utilities; using Xunit; namespace Microsoft.CodeAnalysis.CSharp.Analyzers.UnitTests.RemoveUnnecessaryNullableDirective; @@ -62,6 +63,32 @@ enum EnumName } """); + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/65401")] + public Task TestUnnecessaryDisableEnumDeclaration_WithAttribute() + => VerifyCodeFixAsync( + NullableContextOptions.Enable, + """ + [|#nullable disable|] + using System; + + [CLSCompliant(false)] + enum EnumName + { + First, + Second, + } + """, + """ + using System; + + [CLSCompliant(false)] + enum EnumName + { + First, + Second, + } + """); + [Fact] public Task TestUnnecessaryDisableEnumDeclarationWithFileHeader() => VerifyCodeFixAsync( diff --git a/src/roslyn/src/Analyzers/CSharp/Tests/RemoveUnnecessarySuppressions/RemoveUnnecessaryAttributeSuppressionsTests.cs b/src/roslyn/src/Analyzers/CSharp/Tests/RemoveUnnecessarySuppressions/RemoveUnnecessaryAttributeSuppressionsTests.cs index 47866bc70ca..409cfd9bbe7 100644 --- a/src/roslyn/src/Analyzers/CSharp/Tests/RemoveUnnecessarySuppressions/RemoveUnnecessaryAttributeSuppressionsTests.cs +++ b/src/roslyn/src/Analyzers/CSharp/Tests/RemoveUnnecessarySuppressions/RemoveUnnecessaryAttributeSuppressionsTests.cs @@ -3,17 +3,19 @@ // See the LICENSE file in the project root for more information. using System.Threading.Tasks; +using Microsoft.CodeAnalysis.CSharp.RemoveUnnecessarySuppressions; using Microsoft.CodeAnalysis.Editor.UnitTests.CodeActions; using Microsoft.CodeAnalysis.RemoveUnnecessarySuppressions; using Microsoft.CodeAnalysis.Test.Utilities; using Roslyn.Test.Utilities; using Xunit; -using VerifyCS = Microsoft.CodeAnalysis.Editor.UnitTests.CodeActions.CSharpCodeFixVerifier< - Microsoft.CodeAnalysis.CSharp.RemoveUnnecessarySuppressions.CSharpRemoveUnnecessaryAttributeSuppressionsDiagnosticAnalyzer, - Microsoft.CodeAnalysis.RemoveUnnecessarySuppressions.RemoveUnnecessaryAttributeSuppressionsCodeFixProvider>; namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.RemoveUnnecessarySuppressions; +using VerifyCS = CSharpCodeFixVerifier< + CSharpRemoveUnnecessaryAttributeSuppressionsDiagnosticAnalyzer, + RemoveUnnecessaryAttributeSuppressionsCodeFixProvider>; + [Trait(Traits.Feature, Traits.Features.CodeActionsRemoveUnnecessarySuppressions)] [WorkItem("https://github.com/dotnet/roslyn/issues/44176")] public sealed class RemoveUnnecessaryAttributeSuppressionsTests diff --git a/src/roslyn/src/Analyzers/CSharp/Tests/UpdateLegacySuppressions/UpdateLegacySuppressionsTests.cs b/src/roslyn/src/Analyzers/CSharp/Tests/UpdateLegacySuppressions/UpdateLegacySuppressionsTests.cs index f52eaa57550..a28518bbe36 100644 --- a/src/roslyn/src/Analyzers/CSharp/Tests/UpdateLegacySuppressions/UpdateLegacySuppressionsTests.cs +++ b/src/roslyn/src/Analyzers/CSharp/Tests/UpdateLegacySuppressions/UpdateLegacySuppressionsTests.cs @@ -3,17 +3,20 @@ // See the LICENSE file in the project root for more information. using System.Threading.Tasks; +using Microsoft.CodeAnalysis.CSharp.RemoveUnnecessarySuppressions; using Microsoft.CodeAnalysis.Editor.UnitTests.CodeActions; using Microsoft.CodeAnalysis.RemoveUnnecessarySuppressions; using Microsoft.CodeAnalysis.Test.Utilities; +using Microsoft.CodeAnalysis.UpdateLegacySuppressions; using Roslyn.Test.Utilities; using Xunit; -using VerifyCS = Microsoft.CodeAnalysis.Editor.UnitTests.CodeActions.CSharpCodeFixVerifier< - Microsoft.CodeAnalysis.CSharp.RemoveUnnecessarySuppressions.CSharpRemoveUnnecessaryAttributeSuppressionsDiagnosticAnalyzer, - Microsoft.CodeAnalysis.UpdateLegacySuppressions.UpdateLegacySuppressionsCodeFixProvider>; namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.UpdateLegacySuppressions; +using VerifyCS = CSharpCodeFixVerifier< + CSharpRemoveUnnecessaryAttributeSuppressionsDiagnosticAnalyzer, + UpdateLegacySuppressionsCodeFixProvider>; + [Trait(Traits.Feature, Traits.Features.CodeActionsUpdateLegacySuppressions)] [WorkItem("https://github.com/dotnet/roslyn/issues/44362")] public sealed class UpdateLegacySuppressionsTests diff --git a/src/roslyn/src/Analyzers/CSharp/Tests/UseImplicitOrExplicitType/UseImplicitTypeTests.cs b/src/roslyn/src/Analyzers/CSharp/Tests/UseImplicitOrExplicitType/UseImplicitTypeTests.cs index 818f0e09cd6..75db660d4d9 100644 --- a/src/roslyn/src/Analyzers/CSharp/Tests/UseImplicitOrExplicitType/UseImplicitTypeTests.cs +++ b/src/roslyn/src/Analyzers/CSharp/Tests/UseImplicitOrExplicitType/UseImplicitTypeTests.cs @@ -2097,9 +2097,11 @@ static void M() } """, new TestParameters(options: ImplicitTypeEverywhere())); - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/22768")] - public Task DoNotSuggestVarOnStackAllocExpressions_SpanType_NestedConditional() - => TestMissingInRegularAndScriptAsync(""" + [Fact] + [WorkItem("https://github.com/dotnet/roslyn/issues/22768")] + [WorkItem("https://github.com/dotnet/roslyn/issues/79337")] + public Task DoSuggestVarOnStackAllocExpressions_SpanType_NestedConditional() + => TestInRegularAndScript1Async(""" using System; namespace System { @@ -2115,11 +2117,29 @@ static void M(bool choice) [|Span|] x = choice ? stackalloc int [10] : stackalloc int [100]; } } + """, """ + using System; + namespace System + { + public readonly ref struct Span + { + unsafe public Span(void* pointer, int length) { } + } + } + class C + { + static void M(bool choice) + { + var x = choice ? stackalloc int [10] : stackalloc int [100]; + } + } """, new TestParameters(options: ImplicitTypeEverywhere())); - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/22768")] - public Task DoNotSuggestVarOnStackAllocExpressions_SpanType_NestedCast() - => TestMissingInRegularAndScriptAsync(""" + [Fact] + [WorkItem("https://github.com/dotnet/roslyn/issues/22768")] + [WorkItem("https://github.com/dotnet/roslyn/issues/79337")] + public Task DoSuggestVarOnStackAllocExpressions_SpanType_NestedCast() + => TestInRegularAndScript1Async(""" using System; namespace System { @@ -2135,6 +2155,22 @@ static void M() [|Span|] x = (Span)stackalloc int [100]; } } + """, """ + using System; + namespace System + { + public readonly ref struct Span + { + unsafe public Span(void* pointer, int length) { } + } + } + class C + { + static void M() + { + var x = (Span)stackalloc int [100]; + } + } """, new TestParameters(options: ImplicitTypeEverywhere())); [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/22768")] diff --git a/src/roslyn/src/Analyzers/VisualBasic/Tests/RemoveUnnecessaryParentheses/RemoveUnnecessaryParenthesesTests.vb b/src/roslyn/src/Analyzers/VisualBasic/Tests/RemoveUnnecessaryParentheses/RemoveUnnecessaryParenthesesTests.vb index 9d66369c48b..5b7e600d503 100644 --- a/src/roslyn/src/Analyzers/VisualBasic/Tests/RemoveUnnecessaryParentheses/RemoveUnnecessaryParenthesesTests.vb +++ b/src/roslyn/src/Analyzers/VisualBasic/Tests/RemoveUnnecessaryParentheses/RemoveUnnecessaryParenthesesTests.vb @@ -15,7 +15,7 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.RemoveUnnecessaryP ''' whose current option is set to something other than 'Ignore'. ''' - Partial Public Class RemoveUnnecessaryParenthesesTests + Partial Public NotInheritable Class RemoveUnnecessaryParenthesesTests Inherits AbstractVisualBasicDiagnosticProviderBasedUserDiagnosticTest_NoEditor Private Shared ReadOnly CheckOverflow As CompilationOptions = New VisualBasicCompilationOptions(OutputKind.ConsoleApplication, checkOverflow:=True) @@ -651,7 +651,16 @@ end class" Assert.Equal("[1,2]", diagnostic.Properties.Item(WellKnownDiagnosticTags.Unnecessary)) End Using + End Function + + Public Async Function TestWithNullMemberAccess() As Task + Await TestMissingAsync( +"class C + sub M() + RoundTime($$(d.EndDate - d.StartDate)?.TotalMinutes / 60) + end sub +end class", New TestParameters(options:=RequireArithmeticBinaryParenthesesForClarity)) End Function End Class End Namespace diff --git a/src/roslyn/src/EditorFeatures/CSharpTest/AddMissingImports/CSharpAddMissingImportsRefactoringProviderTests.cs b/src/roslyn/src/EditorFeatures/CSharpTest/AddMissingImports/CSharpAddMissingImportsRefactoringProviderTests.cs index 335d55a65f3..93ceaedbf57 100644 --- a/src/roslyn/src/EditorFeatures/CSharpTest/AddMissingImports/CSharpAddMissingImportsRefactoringProviderTests.cs +++ b/src/roslyn/src/EditorFeatures/CSharpTest/AddMissingImports/CSharpAddMissingImportsRefactoringProviderTests.cs @@ -2,13 +2,14 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#nullable disable - using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Threading.Tasks; +using Microsoft.CodeAnalysis.AddImport; using Microsoft.CodeAnalysis.CodeRefactorings; +using Microsoft.CodeAnalysis.CodeStyle; using Microsoft.CodeAnalysis.CSharp.CodeRefactorings.AddMissingImports; +using Microsoft.CodeAnalysis.CSharp.CodeStyle; using Microsoft.CodeAnalysis.Editing; using Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.CodeRefactorings; using Microsoft.CodeAnalysis.Editor.UnitTests.CodeActions; @@ -26,6 +27,12 @@ public sealed class CSharpAddMissingImportsRefactoringProviderTests : AbstractCS protected override CodeRefactoringProvider CreateCodeRefactoringProvider(EditorTestWorkspace workspace, TestParameters parameters) => new CSharpAddMissingImportsRefactoringProvider(); + private static readonly CodeStyleOption2 InsideNamespaceOption = + new(AddImportPlacement.InsideNamespace, NotificationOption2.Error); + + private static readonly CodeStyleOption2 OutsideNamespaceOption = + new(AddImportPlacement.InsideNamespace, NotificationOption2.Error); + protected override void InitializeWorkspace(EditorTestWorkspace workspace, TestParameters parameters) { // Treat the span being tested as the pasted span @@ -46,13 +53,16 @@ protected override void InitializeWorkspace(EditorTestWorkspace workspace, TestP private Task TestInRegularAndScriptAsync( [StringSyntax(PredefinedEmbeddedLanguageNames.CSharpTest)] string initialMarkup, [StringSyntax(PredefinedEmbeddedLanguageNames.CSharpTest)] string expectedMarkup, - bool placeSystemNamespaceFirst, bool separateImportDirectiveGroups) + bool placeSystemNamespaceFirst, + bool separateImportDirectiveGroups, + bool placeInsideNamespace = false) { var options = new OptionsCollection(GetLanguage()) { { GenerationOptions.PlaceSystemNamespaceFirst, placeSystemNamespaceFirst }, { GenerationOptions.SeparateImportDirectiveGroups, separateImportDirectiveGroups }, + { CSharpCodeStyleOptions.PreferredUsingDirectivePlacement, placeInsideNamespace ? InsideNamespaceOption : OutsideNamespaceOption }, }; return TestInRegularAndScriptAsync(initialMarkup, expectedMarkup, options: options); } @@ -353,4 +363,29 @@ class C List list; } """, placeSystemNamespaceFirst: true, separateImportDirectiveGroups: true); + + [WpfTheory, CombinatorialData, WorkItem("https://github.com/dotnet/roslyn/issues/54842")] + public Task TestWithNamespace(bool placeInsideNamespace) + => TestInRegularAndScriptAsync(""" + namespace N + { + using System; + + class C + { + [|List list;|] + } + } + """, """ + namespace N + { + using System; + using System.Collections.Generic; + + class C + { + List list; + } + } + """, placeSystemNamespaceFirst: true, separateImportDirectiveGroups: true, placeInsideNamespace); } diff --git a/src/roslyn/src/EditorFeatures/CSharpTest/CodeActions/AddUsing/AbstractAddUsingTests.cs b/src/roslyn/src/EditorFeatures/CSharpTest/CodeActions/AddUsing/AbstractAddUsingTests.cs index d739fecb85c..d6cb4ae26b9 100644 --- a/src/roslyn/src/EditorFeatures/CSharpTest/CodeActions/AddUsing/AbstractAddUsingTests.cs +++ b/src/roslyn/src/EditorFeatures/CSharpTest/CodeActions/AddUsing/AbstractAddUsingTests.cs @@ -2,8 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#nullable disable - using System.Diagnostics.CodeAnalysis; using System.Threading.Tasks; using Microsoft.CodeAnalysis.CodeActions; @@ -18,14 +16,10 @@ namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.AddUsing; -public abstract class AbstractAddUsingTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest +public abstract class AbstractAddUsingTests(ITestOutputHelper? logger = null) + : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest(logger) { - protected AbstractAddUsingTests(ITestOutputHelper logger = null) - : base(logger) - { - } - - internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) + internal override (DiagnosticAnalyzer?, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) => (null, new CSharpAddImportCodeFixProvider()); private protected OptionsCollection SeparateGroups => Option(GenerationOptions.SeparateImportDirectiveGroups, true); @@ -36,7 +30,7 @@ internal Task TestAsync( TestHost testHost, int index = 0, CodeActionPriority? priority = null, - OptionsCollection options = null) + OptionsCollection? options = null) => TestInRegularAndScript1Async( initialMarkup, expectedMarkup, diff --git a/src/roslyn/src/EditorFeatures/CSharpTest/CodeActions/AddUsing/AddUsingTests.cs b/src/roslyn/src/EditorFeatures/CSharpTest/CodeActions/AddUsing/AddUsingTests.cs index c9ce5e2cdac..a9f79963b3c 100644 --- a/src/roslyn/src/EditorFeatures/CSharpTest/CodeActions/AddUsing/AddUsingTests.cs +++ b/src/roslyn/src/EditorFeatures/CSharpTest/CodeActions/AddUsing/AddUsingTests.cs @@ -6633,4 +6633,17 @@ class Program """, index: 0, parameters: new TestParameters(testHost: testHost)); + + [Theory, CombinatorialData] + [WorkItem("https://github.com/dotnet/roslyn/issues/72022")] + public Task TestAssemblyLevelAttribute(TestHost testHost) + => TestAsync( + """ + [assembly: [|NeutralResourcesLanguage|]("en")] + """, + """ + using System.Resources; + + [assembly: NeutralResourcesLanguage("en")] + """, testHost); } diff --git a/src/roslyn/src/EditorFeatures/CSharpTest/CodeActions/GenerateEqualsAndGetHashCodeFromMembers/GenerateEqualsAndGetHashCodeFromMembersTests.cs b/src/roslyn/src/EditorFeatures/CSharpTest/CodeActions/GenerateEqualsAndGetHashCodeFromMembers/GenerateEqualsAndGetHashCodeFromMembersTests.cs index cdb2f66eb19..d9bd2d2acc4 100644 --- a/src/roslyn/src/EditorFeatures/CSharpTest/CodeActions/GenerateEqualsAndGetHashCodeFromMembers/GenerateEqualsAndGetHashCodeFromMembersTests.cs +++ b/src/roslyn/src/EditorFeatures/CSharpTest/CodeActions/GenerateEqualsAndGetHashCodeFromMembers/GenerateEqualsAndGetHashCodeFromMembersTests.cs @@ -20,11 +20,12 @@ using Microsoft.CodeAnalysis.Testing; using Roslyn.Test.Utilities; using Xunit; -using VerifyCS = Microsoft.CodeAnalysis.Editor.UnitTests.CodeActions.CSharpCodeRefactoringVerifier< - Microsoft.CodeAnalysis.GenerateEqualsAndGetHashCodeFromMembers.GenerateEqualsAndGetHashCodeFromMembersCodeRefactoringProvider>; namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.GenerateEqualsAndGetHashCodeFromMembers; +using VerifyCS = CSharpCodeRefactoringVerifier< + GenerateEqualsAndGetHashCodeFromMembersCodeRefactoringProvider>; + [UseExportProvider] [Trait(Traits.Feature, Traits.Features.CodeActionsGenerateEqualsAndGetHashCode)] public sealed class GenerateEqualsAndGetHashCodeFromMembersTests @@ -69,10 +70,7 @@ private static OptionsCollection PreferExplicitTypeWithInfo() internal static void EnableOption(ImmutableArray options, string id) { var option = options.FirstOrDefault(o => o.Id == id); - if (option != null) - { - option.Value = true; - } + option?.Value = true; } [Fact] diff --git a/src/roslyn/src/EditorFeatures/CSharpTest/CodeActions/GenerateType/GenerateTypeTests.cs b/src/roslyn/src/EditorFeatures/CSharpTest/CodeActions/GenerateType/GenerateTypeTests.cs index ade0311f695..d42de6fa6e5 100644 --- a/src/roslyn/src/EditorFeatures/CSharpTest/CodeActions/GenerateType/GenerateTypeTests.cs +++ b/src/roslyn/src/EditorFeatures/CSharpTest/CodeActions/GenerateType/GenerateTypeTests.cs @@ -5901,4 +5901,26 @@ internal class Test public int B { get; set; } } """, index: 1); + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/49649")] + public Task TestInTopLevelProgram() + => TestInRegularAndScriptAsync( + """ + var student = new [|Student|]("Youssef"); + Console.WriteLine(student.Name); + """, + """ + var student = new Student("Youssef"); + Console.WriteLine(student.Name); + + internal class Student + { + private string v; + + public Student(string v) + { + this.v = v; + } + } + """, index: 1); } diff --git a/src/roslyn/src/EditorFeatures/CSharpTest/CodeActions/InitializeParameter/InitializeMemberFromPrimaryConstructorParameterTests.cs b/src/roslyn/src/EditorFeatures/CSharpTest/CodeActions/InitializeParameter/InitializeMemberFromPrimaryConstructorParameterTests.cs index 1dd09cc7e77..8f3cab891e6 100644 --- a/src/roslyn/src/EditorFeatures/CSharpTest/CodeActions/InitializeParameter/InitializeMemberFromPrimaryConstructorParameterTests.cs +++ b/src/roslyn/src/EditorFeatures/CSharpTest/CodeActions/InitializeParameter/InitializeMemberFromPrimaryConstructorParameterTests.cs @@ -1349,6 +1349,50 @@ public partial class Goo """); + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/76565")] + public Task TestCouldInitializeThrowingProperty_ButGeneratePropertyInstead() + => TestInRegularAndScript1Async( + """ + using System; + + class C([||]string s) + { + private string S => throw new NotImplementedException(); + } + """, + """ + using System; + + class C(string s) + { + public string S1 { get; } = s; + + private string S => throw new NotImplementedException(); + } + """, index: 1); + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/76565")] + public Task TestCouldInitializeThrowingProperty_ButGenerateFieldInstead() + => TestInRegularAndScript1Async( + """ + using System; + + class C([||]string s) + { + private string S => throw new NotImplementedException(); + } + """, + """ + using System; + + class C(string s) + { + private readonly string s = s; + + private string S => throw new NotImplementedException(); + } + """, index: 2); + [Fact] public Task TestUpdateCodeToReferenceExistingField1() => TestInRegularAndScript1Async( diff --git a/src/roslyn/src/EditorFeatures/CSharpTest/CodeActions/MoveStaticMembers/CSharpMoveStaticMembersTests.cs b/src/roslyn/src/EditorFeatures/CSharpTest/CodeActions/MoveStaticMembers/CSharpMoveStaticMembersTests.cs index 10c97ce96b0..d943b9e2b3c 100644 --- a/src/roslyn/src/EditorFeatures/CSharpTest/CodeActions/MoveStaticMembers/CSharpMoveStaticMembersTests.cs +++ b/src/roslyn/src/EditorFeatures/CSharpTest/CodeActions/MoveStaticMembers/CSharpMoveStaticMembersTests.cs @@ -4,16 +4,19 @@ using System.Collections.Immutable; using System.Threading.Tasks; +using Microsoft.CodeAnalysis.CSharp.CodeRefactorings.MoveStaticMembers; +using Microsoft.CodeAnalysis.Editor.UnitTests.CodeActions; using Microsoft.CodeAnalysis.MoveStaticMembers; using Microsoft.CodeAnalysis.Test.Utilities; using Microsoft.CodeAnalysis.Test.Utilities.MoveStaticMembers; using Roslyn.Test.Utilities; using Xunit; -using VerifyCS = Microsoft.CodeAnalysis.Editor.UnitTests.CodeActions.CSharpCodeRefactoringVerifier< - Microsoft.CodeAnalysis.CSharp.CodeRefactorings.MoveStaticMembers.CSharpMoveStaticMembersRefactoringProvider>; namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.MoveStaticMembers; +using VerifyCS = CSharpCodeRefactoringVerifier< + CSharpMoveStaticMembersRefactoringProvider>; + [UseExportProvider] [Trait(Traits.Feature, Traits.Features.CodeActionsMoveStaticMembers)] public sealed class CSharpMoveStaticMembersTests diff --git a/src/roslyn/src/EditorFeatures/CSharpTest/Diagnostics/AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest.cs b/src/roslyn/src/EditorFeatures/CSharpTest/Diagnostics/AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest.cs index de315e1a800..9ea1e21c7bf 100644 --- a/src/roslyn/src/EditorFeatures/CSharpTest/Diagnostics/AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest.cs +++ b/src/roslyn/src/EditorFeatures/CSharpTest/Diagnostics/AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest.cs @@ -2,21 +2,29 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#nullable disable +#if CODE_STYLE +extern alias CODESTYLE_UTILITIES; +#endif +using System.Diagnostics.CodeAnalysis; +using System.Threading.Tasks; +using Microsoft.CodeAnalysis.CodeActions; using Microsoft.CodeAnalysis.Editor.UnitTests.CodeActions; using Microsoft.CodeAnalysis.Editor.UnitTests.Diagnostics; +using Microsoft.CodeAnalysis.Remote.Testing; using Xunit.Abstractions; namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Diagnostics; -public abstract partial class AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest : AbstractDiagnosticProviderBasedUserDiagnosticTest -{ - protected AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest(ITestOutputHelper logger) - : base(logger) - { - } +#if CODE_STYLE +using OptionsCollectionAlias = CODESTYLE_UTILITIES::Microsoft.CodeAnalysis.Editor.UnitTests.CodeActions.OptionsCollection; +#else +using OptionsCollectionAlias = OptionsCollection; +#endif +public abstract partial class AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest(ITestOutputHelper? logger) + : AbstractDiagnosticProviderBasedUserDiagnosticTest(logger) +{ protected override ParseOptions GetScriptOptions() => Options.Script; protected internal override string GetLanguage() => LanguageNames.CSharp; @@ -151,4 +159,29 @@ public interface IAsyncEnumerator : IAsyncDisposable internal OptionsCollection IgnoreAllParentheses => ParenthesesOptionsProvider.IgnoreAllParentheses; internal OptionsCollection RemoveAllUnnecessaryParentheses => ParenthesesOptionsProvider.RemoveAllUnnecessaryParentheses; internal OptionsCollection RequireAllParenthesesForClarity => ParenthesesOptionsProvider.RequireAllParenthesesForClarity; + + internal new Task TestInRegularAndScript1Async( + [StringSyntax(PredefinedEmbeddedLanguageNames.CSharpTest)] string initialMarkup, + [StringSyntax(PredefinedEmbeddedLanguageNames.CSharpTest)] string expectedMarkup, + int index = 0, + TestParameters? parameters = null) + { + return base.TestInRegularAndScript1Async(initialMarkup, expectedMarkup, index, parameters); + } + + internal new Task TestInRegularAndScriptAsync( + [StringSyntax(PredefinedEmbeddedLanguageNames.CSharpTest)] string initialMarkup, + [StringSyntax(PredefinedEmbeddedLanguageNames.CSharpTest)] string expectedMarkup, + int index = 0, + CodeActionPriority? priority = null, + CompilationOptions? compilationOptions = null, + OptionsCollectionAlias? options = null, + object? fixProviderData = null, + ParseOptions? parseOptions = null, + string? title = null, + TestHost testHost = TestHost.OutOfProcess) + { + return base.TestInRegularAndScriptAsync( + initialMarkup, expectedMarkup, index, priority, compilationOptions, options, fixProviderData, parseOptions, title, testHost); + } } diff --git a/src/roslyn/src/EditorFeatures/Core/InlineRename/InlineRenameSession.cs b/src/roslyn/src/EditorFeatures/Core/InlineRename/InlineRenameSession.cs index c9afd36b6d8..ff3450ab70d 100644 --- a/src/roslyn/src/EditorFeatures/Core/InlineRename/InlineRenameSession.cs +++ b/src/roslyn/src/EditorFeatures/Core/InlineRename/InlineRenameSession.cs @@ -753,12 +753,9 @@ public async Task CommitAsync(bool previewChanges, IUIThreadOperationContext edi previewChanges = previewChanges || PreviewChanges; - if (editorOperationContext is not null) - { - // Prevent Editor's typing responsiveness auto canceling the rename operation. - // InlineRenameSession will call IUIThreadOperationExecutor to sets up our own IUIThreadOperationContext - editorOperationContext.TakeOwnership(); - } + // Prevent Editor's typing responsiveness auto canceling the rename operation. + // InlineRenameSession will call IUIThreadOperationExecutor to sets up our own IUIThreadOperationContext + editorOperationContext?.TakeOwnership(); try { diff --git a/src/roslyn/src/EditorFeatures/Core/InlineRename/UI/Adornment/RenameFlyoutViewModel.cs b/src/roslyn/src/EditorFeatures/Core/InlineRename/UI/Adornment/RenameFlyoutViewModel.cs index 367eeb23440..e5d4ed313e5 100644 --- a/src/roslyn/src/EditorFeatures/Core/InlineRename/UI/Adornment/RenameFlyoutViewModel.cs +++ b/src/roslyn/src/EditorFeatures/Core/InlineRename/UI/Adornment/RenameFlyoutViewModel.cs @@ -333,10 +333,7 @@ protected virtual void Dispose(bool disposing) Session.ReplacementsComputed -= OnReplacementsComputed; Session.CommitStateChange -= CommitStateChange; - if (SmartRenameViewModel is not null) - { - SmartRenameViewModel.Dispose(); - } + SmartRenameViewModel?.Dispose(); UnregisterOleComponent(); } diff --git a/src/roslyn/src/EditorFeatures/Core/Shared/Utilities/CaretPreservingEditTransaction.cs b/src/roslyn/src/EditorFeatures/Core/Shared/Utilities/CaretPreservingEditTransaction.cs index 5bcb2e0203b..7dfdafeb9d9 100644 --- a/src/roslyn/src/EditorFeatures/Core/Shared/Utilities/CaretPreservingEditTransaction.cs +++ b/src/roslyn/src/EditorFeatures/Core/Shared/Utilities/CaretPreservingEditTransaction.cs @@ -93,10 +93,7 @@ public IMergeTextUndoTransactionPolicy? MergePolicy set { - if (_transaction != null) - { - _transaction.MergePolicy = value; - } + _transaction?.MergePolicy = value; } } diff --git a/src/roslyn/src/EditorFeatures/Core/SignatureHelp/Presentation/SignatureHelpPresenter.SignatureHelpPresenterSession.cs b/src/roslyn/src/EditorFeatures/Core/SignatureHelp/Presentation/SignatureHelpPresenter.SignatureHelpPresenterSession.cs index 7dc0a0b51f3..4bdd65c1574 100644 --- a/src/roslyn/src/EditorFeatures/Core/SignatureHelp/Presentation/SignatureHelpPresenter.SignatureHelpPresenterSession.cs +++ b/src/roslyn/src/EditorFeatures/Core/SignatureHelp/Presentation/SignatureHelpPresenter.SignatureHelpPresenterSession.cs @@ -98,10 +98,7 @@ public void PresentItems( Contract.ThrowIfNull(_signatureMap); var defaultValue = _signatureMap.GetValueOrDefault(_selectedItem); - if (_editorSessionOpt != null) - { - _editorSessionOpt.SelectedSignature = defaultValue; - } + _editorSessionOpt?.SelectedSignature = defaultValue; } finally { diff --git a/src/roslyn/src/EditorFeatures/DiagnosticsTestUtilities/CodeActions/AbstractCodeActionTest.cs b/src/roslyn/src/EditorFeatures/DiagnosticsTestUtilities/CodeActions/AbstractCodeActionTest.cs index aa5f7030fb9..7090b5e0b51 100644 --- a/src/roslyn/src/EditorFeatures/DiagnosticsTestUtilities/CodeActions/AbstractCodeActionTest.cs +++ b/src/roslyn/src/EditorFeatures/DiagnosticsTestUtilities/CodeActions/AbstractCodeActionTest.cs @@ -166,10 +166,7 @@ internal static void EnableOptions( internal static void EnableOption(ImmutableArray options, string id) { var option = options.FirstOrDefault(o => o.Id == id); - if (option != null) - { - option.Value = true; - } + option?.Value = true; } internal Task TestWithPickMembersDialogAsync( diff --git a/src/roslyn/src/EditorFeatures/Test2/FindReferences/FindReferencesTests.NamedTypeSymbols.vb b/src/roslyn/src/EditorFeatures/Test2/FindReferences/FindReferencesTests.NamedTypeSymbols.vb index c6d15c0d97a..97c02854545 100644 --- a/src/roslyn/src/EditorFeatures/Test2/FindReferences/FindReferencesTests.NamedTypeSymbols.vb +++ b/src/roslyn/src/EditorFeatures/Test2/FindReferences/FindReferencesTests.NamedTypeSymbols.vb @@ -254,6 +254,66 @@ class var { } Await TestAPIAndFeature(input, kind, host) End Function + + + Public Async Function TestNamedType_TypeOfOperator_Name(kind As TestKind, host As TestHost) As Task + Dim input = + + + + class {|Definition:Celsius|} + { + public {|Definition:Celsius|}() + { + System.Type t = typeof({|ValueUsageInfo.Name:[|$$Celsius|]|}); + } + } + + + + Await TestAPIAndFeature(input, kind, host) + End Function + + + + Public Async Function TestNamedType_SizeOfOperator_Name(kind As TestKind, host As TestHost) As Task + Dim input = + + + + class {|Definition:Celsius|} + { + public {|Definition:Celsius|}() + { + int t = sizeof({|ValueUsageInfo.Name:[|$$Celsius|]|}); + } + } + + + + Await TestAPIAndFeature(input, kind, host) + End Function + + + + Public Async Function TestNamedType_NameOfOperator_Name(kind As TestKind, host As TestHost) As Task + Dim input = + + + + class {|Definition:Celsius|} + { + public {|Definition:Celsius|}() + { + string t = nameof({|ValueUsageInfo.Name:[|$$Celsius|]|}); + } + } + + + + Await TestAPIAndFeature(input, kind, host) + End Function + Public Async Function TestNamedType_InaccessibleType(kind As TestKind, host As TestHost) As Task diff --git a/src/roslyn/src/Features/CSharp/Portable/InitializeParameter/CSharpInitializeMemberFromPrimaryConstructorParameterCodeRefactoringProvider.cs b/src/roslyn/src/Features/CSharp/Portable/InitializeParameter/CSharpInitializeMemberFromPrimaryConstructorParameterCodeRefactoringProvider.cs index c6a60c70f02..4e02d3fe208 100644 --- a/src/roslyn/src/Features/CSharp/Portable/InitializeParameter/CSharpInitializeMemberFromPrimaryConstructorParameterCodeRefactoringProvider.cs +++ b/src/roslyn/src/Features/CSharp/Portable/InitializeParameter/CSharpInitializeMemberFromPrimaryConstructorParameterCodeRefactoringProvider.cs @@ -20,7 +20,6 @@ using Microsoft.CodeAnalysis.Editing; using Microsoft.CodeAnalysis.Formatting; using Microsoft.CodeAnalysis.InitializeParameter; -using Microsoft.CodeAnalysis.Shared.Collections; using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.Shared.Naming; using Roslyn.Utilities; @@ -73,11 +72,18 @@ public override async Task ComputeRefactoringsAsync(CodeRefactoringContext conte var formattingOptions = await document.GetSyntaxFormattingOptionsAsync(cancellationToken).ConfigureAwait(false); var fieldOrProperty = TryFindMatchingUninitializedFieldOrPropertySymbol(); - var refactorings = fieldOrProperty == null - ? HandleNoExistingFieldOrProperty() - : HandleExistingFieldOrProperty(); + using var refactorings = TemporaryArray.Empty; + if (fieldOrProperty != null) + { + // Found a field/property that this parameter should be assigned to. Just offer the simple assignment to it. + refactorings.Add(CreateCodeAction( + string.Format(fieldOrProperty.Kind == SymbolKind.Field ? FeaturesResources.Initialize_field_0 : FeaturesResources.Initialize_property_0, fieldOrProperty.Name), + cancellationToken => AddAssignmentForPrimaryConstructorAsync(document, parameter, fieldOrProperty, cancellationToken))); + } + + AddCreateFieldOrPropertyCodeActions(); - context.RegisterRefactorings(refactorings.ToImmutableArray(), context.Span); + context.RegisterRefactorings(refactorings.ToImmutableAndClear(), context.Span); return; ISymbol? TryFindMatchingUninitializedFieldOrPropertySymbol() @@ -133,15 +139,7 @@ public override async Task ComputeRefactoringsAsync(CodeRefactoringContext conte static CodeAction CreateCodeAction(string title, Func> createSolution) => CodeAction.Create(title, createSolution, title); - IEnumerable HandleExistingFieldOrProperty() - { - // Found a field/property that this parameter should be assigned to. Just offer the simple assignment to it. - yield return CreateCodeAction( - string.Format(fieldOrProperty.Kind == SymbolKind.Field ? FeaturesResources.Initialize_field_0 : FeaturesResources.Initialize_property_0, fieldOrProperty.Name), - cancellationToken => AddAssignmentForPrimaryConstructorAsync(document, parameter, fieldOrProperty, cancellationToken)); - } - - IEnumerable HandleNoExistingFieldOrProperty() + void AddCreateFieldOrPropertyCodeActions() { // Didn't find a field/prop that this parameter could be assigned to. Offer to create new one and assign to that. @@ -159,8 +157,8 @@ IEnumerable HandleNoExistingFieldOrProperty() string.Format(FeaturesResources.Create_and_assign_property_0, property.Name), cancellationToken => AddMultipleMembersAsync(document, typeDeclaration, [parameter], [property], cancellationToken)); - yield return siblingFieldOrProperty is IFieldSymbol ? fieldAction : propertyAction; - yield return siblingFieldOrProperty is IFieldSymbol ? propertyAction : fieldAction; + refactorings.Add(siblingFieldOrProperty is IFieldSymbol ? fieldAction : propertyAction); + refactorings.Add(siblingFieldOrProperty is IFieldSymbol ? propertyAction : fieldAction); var parameters = GetParametersWithoutAssociatedMembers(); if (parameters.Length >= 2) @@ -172,8 +170,8 @@ IEnumerable HandleNoExistingFieldOrProperty() FeaturesResources.Create_and_assign_remaining_as_properties, cancellationToken => AddMultipleMembersAsync(document, typeDeclaration, parameters, parameters.SelectAsArray(CreateProperty), cancellationToken)); - yield return siblingFieldOrProperty is IFieldSymbol ? allFieldsAction : allPropertiesAction; - yield return siblingFieldOrProperty is IFieldSymbol ? allPropertiesAction : allFieldsAction; + refactorings.Add(siblingFieldOrProperty is IFieldSymbol ? allFieldsAction : allPropertiesAction); + refactorings.Add(siblingFieldOrProperty is IFieldSymbol ? allPropertiesAction : allFieldsAction); } } diff --git a/src/roslyn/src/Features/CSharpTest/GenerateComparisonOperators/GenerateComparisonOperatorsTests.cs b/src/roslyn/src/Features/CSharpTest/GenerateComparisonOperators/GenerateComparisonOperatorsTests.cs index 37992126de4..3263b9dcd50 100644 --- a/src/roslyn/src/Features/CSharpTest/GenerateComparisonOperators/GenerateComparisonOperatorsTests.cs +++ b/src/roslyn/src/Features/CSharpTest/GenerateComparisonOperators/GenerateComparisonOperatorsTests.cs @@ -7,14 +7,16 @@ using System.Threading.Tasks; using Microsoft.CodeAnalysis.CSharp.CodeStyle; using Microsoft.CodeAnalysis.Editor.UnitTests.CodeActions; +using Microsoft.CodeAnalysis.GenerateComparisonOperators; using Microsoft.CodeAnalysis.Test.Utilities; using Roslyn.Test.Utilities; using Xunit; -using VerifyCS = Microsoft.CodeAnalysis.Editor.UnitTests.CodeActions.CSharpCodeRefactoringVerifier< - Microsoft.CodeAnalysis.GenerateComparisonOperators.GenerateComparisonOperatorsCodeRefactoringProvider>; namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.GenerateComparisonOperators; +using VerifyCS = CSharpCodeRefactoringVerifier< + GenerateComparisonOperatorsCodeRefactoringProvider>; + [UseExportProvider] [Trait(Traits.Feature, Traits.Features.CodeActionsGenerateComparisonOperators)] public sealed class GenerateComparisonOperatorsTests diff --git a/src/roslyn/src/Features/Core/Portable/GenerateOverrides/GenerateOverridesWithDialogCodeAction.cs b/src/roslyn/src/Features/Core/Portable/GenerateOverrides/GenerateOverridesWithDialogCodeAction.cs index bd8c52909be..049fbf52bbe 100644 --- a/src/roslyn/src/Features/Core/Portable/GenerateOverrides/GenerateOverridesWithDialogCodeAction.cs +++ b/src/roslyn/src/Features/Core/Portable/GenerateOverrides/GenerateOverridesWithDialogCodeAction.cs @@ -102,10 +102,7 @@ private sealed class ChangeOptionValueOperation(bool selectedAll) : CodeActionOp public override void Apply(Workspace workspace, CancellationToken cancellationToken) { var service = workspace.Services.GetService(); - if (service != null) - { - service.GenerateOverrides = _selectedAll; - } + service?.GenerateOverrides = _selectedAll; } } } diff --git a/src/roslyn/src/Features/Core/Portable/GenerateType/AbstractGenerateTypeService.cs b/src/roslyn/src/Features/Core/Portable/GenerateType/AbstractGenerateTypeService.cs index 0ebac83ad0f..2309c81eb50 100644 --- a/src/roslyn/src/Features/Core/Portable/GenerateType/AbstractGenerateTypeService.cs +++ b/src/roslyn/src/Features/Core/Portable/GenerateType/AbstractGenerateTypeService.cs @@ -13,6 +13,7 @@ using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CodeActions; using Microsoft.CodeAnalysis.CodeGeneration; +using Microsoft.CodeAnalysis.Collections; using Microsoft.CodeAnalysis.Internal.Log; using Microsoft.CodeAnalysis.LanguageService; using Microsoft.CodeAnalysis.PooledObjects; @@ -100,7 +101,7 @@ private ImmutableArray GetActions( State state, CancellationToken cancellationToken) { - using var _ = ArrayBuilder.GetInstance(out var result); + using var result = TemporaryArray.Empty; var generateNewTypeInDialog = false; if (state.NamespaceToGenerateInOpt != null) diff --git a/src/roslyn/src/Features/Core/Portable/QuickInfo/QuickInfoUtilities.cs b/src/roslyn/src/Features/Core/Portable/QuickInfo/QuickInfoUtilities.cs index bdce9d78b0c..a2a2490d683 100644 --- a/src/roslyn/src/Features/Core/Portable/QuickInfo/QuickInfoUtilities.cs +++ b/src/roslyn/src/Features/Core/Portable/QuickInfo/QuickInfoUtilities.cs @@ -77,10 +77,7 @@ public static async Task CreateQuickInfoItemAsync( if (groups.TryGetValue(SymbolDescriptionGroups.Documentation, out var docParts) && !docParts.IsDefaultOrEmpty) { AddSection(QuickInfoSectionKinds.DocumentationComments, docParts); - if (onTheFlyDocsInfo != null) - { - onTheFlyDocsInfo.HasComments = true; - } + onTheFlyDocsInfo?.HasComments = true; } if (options.QuickInfoOptions.ShowRemarksInQuickInfo && diff --git a/src/roslyn/src/Features/Core/Portable/ReplacePropertyWithMethods/ReplacePropertyWithMethodsCodeRefactoringProvider.cs b/src/roslyn/src/Features/Core/Portable/ReplacePropertyWithMethods/ReplacePropertyWithMethodsCodeRefactoringProvider.cs index ccd8de06085..53ef252db13 100644 --- a/src/roslyn/src/Features/Core/Portable/ReplacePropertyWithMethods/ReplacePropertyWithMethodsCodeRefactoringProvider.cs +++ b/src/roslyn/src/Features/Core/Portable/ReplacePropertyWithMethods/ReplacePropertyWithMethodsCodeRefactoringProvider.cs @@ -263,13 +263,10 @@ private async Task ReplaceReferencesAsync( editor.ReplaceNode(parent, parent.WithAdditionalAnnotations( ConflictAnnotation.Create(FeaturesResources.Property_referenced_implicitly))); } - else if (syntaxFacts.IsMemberInitializerNamedAssignmentIdentifier(parent)) - { - editor.ReplaceNode(parent, parent.WithAdditionalAnnotations( - ConflictAnnotation.Create(FeaturesResources.Property_reference_cannot_be_updated))); - } - else if (syntaxFacts.IsNameOfSubpattern(parent)) + else if (IsInNonUpdatableLocation(syntaxFacts, parent)) { + // If the property is in a location where it cannot be updated, then just + // replace it with a warning. editor.ReplaceNode(parent, parent.WithAdditionalAnnotations( ConflictAnnotation.Create(FeaturesResources.Property_reference_cannot_be_updated))); } @@ -284,6 +281,13 @@ await service.ReplaceReferenceAsync( } } } + + static bool IsInNonUpdatableLocation(ISyntaxFacts syntaxFacts, SyntaxNode parent) + { + return syntaxFacts.IsMemberInitializerNamedAssignmentIdentifier(parent) || + syntaxFacts.IsNameOfSubpattern(parent) || + syntaxFacts.IsInNamespaceOrTypeContext(parent); + } } private static async Task ReplaceDefinitionsWithMethodsAsync( diff --git a/src/roslyn/src/Features/DiagnosticsTestUtilities/CodeActionsLegacy/AbstractCodeActionTest_NoEditor.cs b/src/roslyn/src/Features/DiagnosticsTestUtilities/CodeActionsLegacy/AbstractCodeActionTest_NoEditor.cs index 887450a6e6f..12d8bd9c7eb 100644 --- a/src/roslyn/src/Features/DiagnosticsTestUtilities/CodeActionsLegacy/AbstractCodeActionTest_NoEditor.cs +++ b/src/roslyn/src/Features/DiagnosticsTestUtilities/CodeActionsLegacy/AbstractCodeActionTest_NoEditor.cs @@ -174,10 +174,7 @@ internal static void EnableOptions( internal static void EnableOption(ImmutableArray options, string id) { var option = options.FirstOrDefault(o => o.Id == id); - if (option != null) - { - option.Value = true; - } + option?.Value = true; } internal Task TestWithPickMembersDialogAsync( diff --git a/src/roslyn/src/Features/VisualBasicTest/ReplacePropertyWithMethods/ReplacePropertyWithMethodsTests.vb b/src/roslyn/src/Features/VisualBasicTest/ReplacePropertyWithMethods/ReplacePropertyWithMethodsTests.vb index ba62265f778..fe7c9d8b76e 100644 --- a/src/roslyn/src/Features/VisualBasicTest/ReplacePropertyWithMethods/ReplacePropertyWithMethodsTests.vb +++ b/src/roslyn/src/Features/VisualBasicTest/ReplacePropertyWithMethods/ReplacePropertyWithMethodsTests.vb @@ -8,7 +8,7 @@ Imports Microsoft.CodeAnalysis.ReplacePropertyWithMethods Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.CodeActions.ReplacePropertyWithMethods - Public Class ReplacePropertyWithMethodsTests + Public NotInheritable Class ReplacePropertyWithMethodsTests Inherits AbstractVisualBasicCodeActionTest_NoEditor Protected Overrides Function CreateCodeRefactoringProvider(workspace As TestWorkspace, parameters As TestParameters) As CodeRefactoringProvider @@ -698,5 +698,24 @@ Class C End Sub End Class") End Function + + + Public Async Function TestPropertyNameReferencedInAsClause() As Task + Await TestInRegularAndScriptAsync( +"class C + property [||]Goo as Goo +end class", +"class C + Private _Goo As Goo + + Public Function GetGoo() As Goo + Return _Goo + End Function + + Public Sub SetGoo(AutoPropertyValue As Goo) + _Goo = AutoPropertyValue + End Sub +end class") + End Function End Class End Namespace diff --git a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/ResxGeneratorTests.cs b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/ResxGeneratorTests.cs index 7f723ad532d..55bea2fa656 100644 --- a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/ResxGeneratorTests.cs +++ b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/ResxGeneratorTests.cs @@ -5,860 +5,860 @@ using System.Threading.Tasks; using Xunit; using CSharpLanguageVersion = Microsoft.CodeAnalysis.CSharp.LanguageVersion; -using VerifyCS = Microsoft.CodeAnalysis.ResxSourceGenerator.Test.CSharpSourceGeneratorVerifier; -using VerifyVB = Microsoft.CodeAnalysis.ResxSourceGenerator.Test.VisualBasicSourceGeneratorVerifier; -namespace Microsoft.CodeAnalysis.ResxSourceGenerator.Test +namespace Microsoft.CodeAnalysis.ResxSourceGenerator.Test; + +using VerifyCS = CSharpSourceGeneratorVerifier; +using VerifyVB = VisualBasicSourceGeneratorVerifier; + +public sealed class ResxGeneratorTests { - public class ResxGeneratorTests + private const string ResxHeader = """ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + """; + private const string ResxFooter = """ + + """; + + [Theory] + [InlineData(CSharpLanguageVersion.CSharp5, Skip = "Expression-bodied members are not supported in C# 5")] + [InlineData(CSharpLanguageVersion.CSharp6)] + [InlineData(CSharpLanguageVersion.CSharp7)] + [InlineData(CSharpLanguageVersion.CSharp8)] + [InlineData(CSharpLanguageVersion.CSharp9)] + public async Task SingleString_DefaultCSharpAsync(CSharpLanguageVersion languageVersion) { - private const string ResxHeader = """ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - """; - private const string ResxFooter = """ - - """; - - [Theory] - [InlineData(CSharpLanguageVersion.CSharp5, Skip = "Expression-bodied members are not supported in C# 5")] - [InlineData(CSharpLanguageVersion.CSharp6)] - [InlineData(CSharpLanguageVersion.CSharp7)] - [InlineData(CSharpLanguageVersion.CSharp8)] - [InlineData(CSharpLanguageVersion.CSharp9)] - public async Task SingleString_DefaultCSharpAsync(CSharpLanguageVersion languageVersion) + var code = ResxHeader + + """ + + value + comment + + """ + + ResxFooter; + + await new VerifyCS.Test(identifier: languageVersion.ToString()) { - var code = ResxHeader - + """ - - value - comment - - """ - + ResxFooter; - - await new VerifyCS.Test(identifier: languageVersion.ToString()) + LanguageVersion = languageVersion, + TestState = { - LanguageVersion = languageVersion, - TestState = - { - Sources = { "" }, - AdditionalFiles = { ("/0/Resources.resx", code) }, - }, - }.AddGeneratedSources().RunAsync(); - } + Sources = { "" }, + AdditionalFiles = { ("/0/Resources.resx", code) }, + }, + }.AddGeneratedSources().RunAsync(); + } - [Fact] - public async Task TwoResourcesSameName_DefaultCSharpAsync() + [Fact] + public async Task TwoResourcesSameName_DefaultCSharpAsync() + { + var code = ResxHeader + + """ + + value + comment + + """ + + ResxFooter; + + await new VerifyCS.Test() { - var code = ResxHeader - + """ - - value - comment - - """ - + ResxFooter; - - await new VerifyCS.Test() + TestState = { - TestState = + Sources = { "" }, + AdditionalFiles = { - Sources = { "" }, - AdditionalFiles = - { - ("/0/First/Resources.resx", code), - ("/0/Second/Resources.resx", code), - }, - AnalyzerConfigFiles = - { - ("/.globalconfig", $""" - is_global = true - - build_property.RootNamespace = TestProject - - [/0/First/Resources.resx] - build_metadata.AdditionalFiles.RelativeDir = First/ - - [/0/Second/Resources.resx] - build_metadata.AdditionalFiles.RelativeDir = Second/ - """), - }, + ("/0/First/Resources.resx", code), + ("/0/Second/Resources.resx", code), }, - }.AddGeneratedSources().RunAsync(); - } + AnalyzerConfigFiles = + { + ("/.globalconfig", $""" + is_global = true - [Fact] - public async Task TwoResourcesSameName_DefaultVisualBasicAsync() + build_property.RootNamespace = TestProject + + [/0/First/Resources.resx] + build_metadata.AdditionalFiles.RelativeDir = First/ + + [/0/Second/Resources.resx] + build_metadata.AdditionalFiles.RelativeDir = Second/ + """), + }, + }, + }.AddGeneratedSources().RunAsync(); + } + + [Fact] + public async Task TwoResourcesSameName_DefaultVisualBasicAsync() + { + var code = ResxHeader + + """ + + value + comment + + """ + + ResxFooter; + + await new VerifyVB.Test() { - var code = ResxHeader - + """ - - value - comment - - """ - + ResxFooter; - - await new VerifyVB.Test() + TestState = { - TestState = + Sources = { "" }, + AdditionalFiles = { - Sources = { "" }, - AdditionalFiles = - { - ("/0/First/Resources.resx", code), - ("/0/Second/Resources.resx", code), - }, - AnalyzerConfigFiles = - { - ("/.globalconfig", $""" - is_global = true - - build_property.RootNamespace = TestProject - - [/0/First/Resources.resx] - build_metadata.AdditionalFiles.RelativeDir = First/ - - [/0/Second/Resources.resx] - build_metadata.AdditionalFiles.RelativeDir = Second/ - """), - }, + ("/0/First/Resources.resx", code), + ("/0/Second/Resources.resx", code), + }, + AnalyzerConfigFiles = + { + ("/.globalconfig", $""" + is_global = true + + build_property.RootNamespace = TestProject + + [/0/First/Resources.resx] + build_metadata.AdditionalFiles.RelativeDir = First/ + + [/0/Second/Resources.resx] + build_metadata.AdditionalFiles.RelativeDir = Second/ + """), }, - }.AddGeneratedSources().RunAsync(); - } + }, + }.AddGeneratedSources().RunAsync(); + } - [Fact] - public async Task SingleString_DefaultVisualBasicAsync() + [Fact] + public async Task SingleString_DefaultVisualBasicAsync() + { + var code = ResxHeader + + """ + + value + comment + + """ + + ResxFooter; + + await new VerifyVB.Test { - var code = ResxHeader - + """ - - value - comment - - """ - + ResxFooter; - - await new VerifyVB.Test + TestState = { - TestState = - { - AdditionalFiles = { ("/0/Resources.resx", code) }, - }, - }.AddGeneratedSources().RunAsync(); - } + AdditionalFiles = { ("/0/Resources.resx", code) }, + }, + }.AddGeneratedSources().RunAsync(); + } - [Fact] - public async Task SingleString_DisableCodeGenAsync() + [Fact] + public async Task SingleString_DisableCodeGenAsync() + { + var code = ResxHeader + + """ + + value + comment + + """ + + ResxFooter; + + await new VerifyCS.Test { - var code = ResxHeader - + """ - - value - comment - - """ - + ResxFooter; - - await new VerifyCS.Test + TestState = { - TestState = + Sources = { "" }, + AdditionalFiles = { ("/0/Resources.resx", code) }, + AnalyzerConfigFiles = { - Sources = { "" }, - AdditionalFiles = { ("/0/Resources.resx", code) }, - AnalyzerConfigFiles = - { - ("/.globalconfig", """ - is_global = true - - [/0/Resources.resx] - build_metadata.AdditionalFiles.GenerateSource = false - """), - }, + ("/.globalconfig", """ + is_global = true + + [/0/Resources.resx] + build_metadata.AdditionalFiles.GenerateSource = false + """), }, - }.RunAsync(); + }, + }.RunAsync(); - await new VerifyVB.Test + await new VerifyVB.Test + { + TestState = { - TestState = + Sources = { "" }, + AdditionalFiles = { ("/0/Resources.resx", code) }, + AnalyzerConfigFiles = { - Sources = { "" }, - AdditionalFiles = { ("/0/Resources.resx", code) }, - AnalyzerConfigFiles = - { - ("/.globalconfig", """ - is_global = true - - [/0/Resources.resx] - build_metadata.AdditionalFiles.GenerateSource = false - """), - }, + ("/.globalconfig", """ + is_global = true + + [/0/Resources.resx] + build_metadata.AdditionalFiles.GenerateSource = false + """), }, - }.RunAsync(); - } - - [Theory] - [InlineData("")] - [InlineData("NS")] - [InlineData("NS1.NS2")] - public async Task SingleString_RootNamespaceCSharpAsync(string rootNamespace) + }, + }.RunAsync(); + } + + [Theory] + [InlineData("")] + [InlineData("NS")] + [InlineData("NS1.NS2")] + public async Task SingleString_RootNamespaceCSharpAsync(string rootNamespace) + { + var code = ResxHeader + + """ + + value + comment + + """ + + ResxFooter; + + await new VerifyCS.Test(identifier: rootNamespace) { - var code = ResxHeader - + """ - - value - comment - - """ - + ResxFooter; - - await new VerifyCS.Test(identifier: rootNamespace) + TestState = { - TestState = + AdditionalFiles = { ("/0/Resources.resx", code) }, + AnalyzerConfigFiles = { - AdditionalFiles = { ("/0/Resources.resx", code) }, - AnalyzerConfigFiles = - { - ("/.globalconfig", $""" - is_global = true - - build_property.RootNamespace = {rootNamespace} - """), - }, + ("/.globalconfig", $""" + is_global = true + + build_property.RootNamespace = {rootNamespace} + """), }, - }.AddGeneratedSources().RunAsync(); - } - - [Theory] - [InlineData("")] - [InlineData("NS")] - [InlineData("NS1.NS2")] - public async Task SingleString_RootNamespaceVisualBasicAsync(string rootNamespace) + }, + }.AddGeneratedSources().RunAsync(); + } + + [Theory] + [InlineData("")] + [InlineData("NS")] + [InlineData("NS1.NS2")] + public async Task SingleString_RootNamespaceVisualBasicAsync(string rootNamespace) + { + var code = ResxHeader + + """ + + value + comment + + """ + + ResxFooter; + + await new VerifyVB.Test(identifier: rootNamespace) { - var code = ResxHeader - + """ - - value - comment - - """ - + ResxFooter; - - await new VerifyVB.Test(identifier: rootNamespace) + TestState = { - TestState = + AdditionalFiles = { ("/0/Resources.resx", code) }, + AnalyzerConfigFiles = { - AdditionalFiles = { ("/0/Resources.resx", code) }, - AnalyzerConfigFiles = - { - ("/.globalconfig", $""" - is_global = true - - build_property.RootNamespace = {rootNamespace} - """), - }, + ("/.globalconfig", $""" + is_global = true + + build_property.RootNamespace = {rootNamespace} + """), }, - }.AddGeneratedSources().RunAsync(); - } - - [Theory] - [InlineData("")] - [InlineData("NS")] - [InlineData("NS1.NS2")] - public async Task SingleString_RelativeDirCSharpAsync(string relativeDir) + }, + }.AddGeneratedSources().RunAsync(); + } + + [Theory] + [InlineData("")] + [InlineData("NS")] + [InlineData("NS1.NS2")] + public async Task SingleString_RelativeDirCSharpAsync(string relativeDir) + { + var code = ResxHeader + + """ + + value + comment + + """ + + ResxFooter; + + await new VerifyCS.Test(identifier: relativeDir) { - var code = ResxHeader - + """ - - value - comment - - """ - + ResxFooter; - - await new VerifyCS.Test(identifier: relativeDir) + TestState = { - TestState = + AdditionalFiles = { ("/0/Resources.resx", code) }, + AnalyzerConfigFiles = { - AdditionalFiles = { ("/0/Resources.resx", code) }, - AnalyzerConfigFiles = - { - ("/.globalconfig", $""" - is_global = true - - [/0/Resources.resx] - build_metadata.AdditionalFiles.RelativeDir = {relativeDir} - """), - }, + ("/.globalconfig", $""" + is_global = true + + [/0/Resources.resx] + build_metadata.AdditionalFiles.RelativeDir = {relativeDir} + """), }, - }.AddGeneratedSources().RunAsync(); - } - - [Theory] - [InlineData("")] - [InlineData("NS")] - [InlineData("NS1.NS2")] - public async Task SingleString_RelativeDirVisualBasicAsync(string relativeDir) + }, + }.AddGeneratedSources().RunAsync(); + } + + [Theory] + [InlineData("")] + [InlineData("NS")] + [InlineData("NS1.NS2")] + public async Task SingleString_RelativeDirVisualBasicAsync(string relativeDir) + { + var code = ResxHeader + + """ + + value + comment + + """ + + ResxFooter; + + await new VerifyVB.Test(identifier: relativeDir) { - var code = ResxHeader - + """ - - value - comment - - """ - + ResxFooter; - - await new VerifyVB.Test(identifier: relativeDir) + TestState = { - TestState = + AdditionalFiles = { ("/0/Resources.resx", code) }, + AnalyzerConfigFiles = { - AdditionalFiles = { ("/0/Resources.resx", code) }, - AnalyzerConfigFiles = - { - ("/.globalconfig", $""" - is_global = true - - [/0/Resources.resx] - build_metadata.AdditionalFiles.RelativeDir = {relativeDir} - """), - }, + ("/.globalconfig", $""" + is_global = true + + [/0/Resources.resx] + build_metadata.AdditionalFiles.RelativeDir = {relativeDir} + """), }, - }.AddGeneratedSources().RunAsync(); - } - - [Theory] - [InlineData("")] - [InlineData("NS")] - [InlineData("NS1.NS2")] - public async Task SingleString_ClassNameCSharpAsync(string className) + }, + }.AddGeneratedSources().RunAsync(); + } + + [Theory] + [InlineData("")] + [InlineData("NS")] + [InlineData("NS1.NS2")] + public async Task SingleString_ClassNameCSharpAsync(string className) + { + var code = ResxHeader + + """ + + value + comment + + """ + + ResxFooter; + + await new VerifyCS.Test(identifier: className) { - var code = ResxHeader - + """ - - value - comment - - """ - + ResxFooter; - - await new VerifyCS.Test(identifier: className) + TestState = { - TestState = + AdditionalFiles = { ("/0/Resources.resx", code) }, + AnalyzerConfigFiles = { - AdditionalFiles = { ("/0/Resources.resx", code) }, - AnalyzerConfigFiles = - { - ("/.globalconfig", $""" - is_global = true - - [/0/Resources.resx] - build_metadata.AdditionalFiles.ClassName = {className} - """), - }, + ("/.globalconfig", $""" + is_global = true + + [/0/Resources.resx] + build_metadata.AdditionalFiles.ClassName = {className} + """), }, - }.AddGeneratedSources().RunAsync(); - } - - [Theory] - [InlineData("")] - [InlineData("NS")] - [InlineData("NS1.NS2")] - public async Task SingleString_ClassNameVisualBasicAsync(string className) + }, + }.AddGeneratedSources().RunAsync(); + } + + [Theory] + [InlineData("")] + [InlineData("NS")] + [InlineData("NS1.NS2")] + public async Task SingleString_ClassNameVisualBasicAsync(string className) + { + var code = ResxHeader + + """ + + value + comment + + """ + + ResxFooter; + + await new VerifyVB.Test(identifier: className) { - var code = ResxHeader - + """ - - value - comment - - """ - + ResxFooter; - - await new VerifyVB.Test(identifier: className) + TestState = { - TestState = + AdditionalFiles = { ("/0/Resources.resx", code) }, + AnalyzerConfigFiles = { - AdditionalFiles = { ("/0/Resources.resx", code) }, - AnalyzerConfigFiles = - { - ("/.globalconfig", $""" - is_global = true - - [/0/Resources.resx] - build_metadata.AdditionalFiles.ClassName = {className} - """), - }, + ("/.globalconfig", $""" + is_global = true + + [/0/Resources.resx] + build_metadata.AdditionalFiles.ClassName = {className} + """), }, - }.AddGeneratedSources().RunAsync(); - } + }, + }.AddGeneratedSources().RunAsync(); + } - [Theory] - [CombinatorialData] - public async Task SingleString_OmitGetResourceStringCSharpAsync(bool omitGetResourceString) - { - var code = ResxHeader - + """ - - value - comment - - """ - + ResxFooter; - - var customGetResourceString = """ - #nullable enable - - namespace TestProject + [Theory] + [CombinatorialData] + public async Task SingleString_OmitGetResourceStringCSharpAsync(bool omitGetResourceString) + { + var code = ResxHeader + + """ + + value + comment + + """ + + ResxFooter; + + var customGetResourceString = """ + #nullable enable + + namespace TestProject + { + internal static partial class Resources { - internal static partial class Resources - { - internal static string? GetResourceString(string resourceKey, string? defaultValue = null) => throw null!; - } + internal static string? GetResourceString(string resourceKey, string? defaultValue = null) => throw null!; } - """; + } + """; - await new VerifyCS.Test(identifier: omitGetResourceString.ToString()) + await new VerifyCS.Test(identifier: omitGetResourceString.ToString()) + { + TestState = { - TestState = + Sources = { omitGetResourceString ? customGetResourceString : "" }, + AdditionalFiles = { ("/0/Resources.resx", code) }, + AnalyzerConfigFiles = { - Sources = { omitGetResourceString ? customGetResourceString : "" }, - AdditionalFiles = { ("/0/Resources.resx", code) }, - AnalyzerConfigFiles = - { - ("/.globalconfig", $""" - is_global = true - - [/0/Resources.resx] - build_metadata.AdditionalFiles.OmitGetResourceString = {(omitGetResourceString ? "true" : "false")} - """), - }, + ("/.globalconfig", $""" + is_global = true + + [/0/Resources.resx] + build_metadata.AdditionalFiles.OmitGetResourceString = {(omitGetResourceString ? "true" : "false")} + """), }, - }.AddGeneratedSources().RunAsync(); - } + }, + }.AddGeneratedSources().RunAsync(); + } - [Theory] - [CombinatorialData] - public async Task SingleString_OmitGetResourceStringVisualBasicAsync(bool omitGetResourceString) + [Theory] + [CombinatorialData] + public async Task SingleString_OmitGetResourceStringVisualBasicAsync(bool omitGetResourceString) + { + var code = ResxHeader + + """ + + value + comment + + """ + + ResxFooter; + + var customGetResourceString = """ + Namespace Global.TestProject + Friend Partial Class Resources + Friend Shared Function GetResourceString(resourceKey As String, Optional defaultValue As String = Nothing) + Return "" + End Function + End Class + End Namespace + """; + + await new VerifyVB.Test(identifier: omitGetResourceString.ToString()) { - var code = ResxHeader - + """ - - value - comment - - """ - + ResxFooter; - - var customGetResourceString = """ - Namespace Global.TestProject - Friend Partial Class Resources - Friend Shared Function GetResourceString(resourceKey As String, Optional defaultValue As String = Nothing) - Return "" - End Function - End Class - End Namespace - """; - - await new VerifyVB.Test(identifier: omitGetResourceString.ToString()) + TestState = { - TestState = + Sources = { omitGetResourceString ? customGetResourceString : "" }, + AdditionalFiles = { ("/0/Resources.resx", code) }, + AnalyzerConfigFiles = { - Sources = { omitGetResourceString ? customGetResourceString : "" }, - AdditionalFiles = { ("/0/Resources.resx", code) }, - AnalyzerConfigFiles = - { - ("/.globalconfig", $""" - is_global = true - - [/0/Resources.resx] - build_metadata.AdditionalFiles.OmitGetResourceString = {(omitGetResourceString ? "true" : "false")} - """), - }, + ("/.globalconfig", $""" + is_global = true + + [/0/Resources.resx] + build_metadata.AdditionalFiles.OmitGetResourceString = {(omitGetResourceString ? "true" : "false")} + """), }, - }.AddGeneratedSources().RunAsync(); - } + }, + }.AddGeneratedSources().RunAsync(); + } - [Theory] - [CombinatorialData] - public async Task SingleString_AsConstantsCSharpAsync(bool asConstants) + [Theory] + [CombinatorialData] + public async Task SingleString_AsConstantsCSharpAsync(bool asConstants) + { + var code = ResxHeader + + """ + + value + comment + + """ + + ResxFooter; + + await new VerifyCS.Test(identifier: asConstants.ToString()) { - var code = ResxHeader - + """ - - value - comment - - """ - + ResxFooter; - - await new VerifyCS.Test(identifier: asConstants.ToString()) + TestState = { - TestState = + AdditionalFiles = { ("/0/Resources.resx", code) }, + AnalyzerConfigFiles = { - AdditionalFiles = { ("/0/Resources.resx", code) }, - AnalyzerConfigFiles = - { - ("/.globalconfig", $""" - is_global = true - - [/0/Resources.resx] - build_metadata.AdditionalFiles.AsConstants = {(asConstants ? "true" : "false")} - """), - }, + ("/.globalconfig", $""" + is_global = true + + [/0/Resources.resx] + build_metadata.AdditionalFiles.AsConstants = {(asConstants ? "true" : "false")} + """), }, - }.AddGeneratedSources().RunAsync(); - } + }, + }.AddGeneratedSources().RunAsync(); + } - [Theory] - [CombinatorialData] - public async Task SingleString_AsConstantsVisualBasicAsync(bool asConstants) + [Theory] + [CombinatorialData] + public async Task SingleString_AsConstantsVisualBasicAsync(bool asConstants) + { + var code = ResxHeader + + """ + + value + comment + + """ + + ResxFooter; + + await new VerifyVB.Test(identifier: asConstants.ToString()) { - var code = ResxHeader - + """ - - value - comment - - """ - + ResxFooter; - - await new VerifyVB.Test(identifier: asConstants.ToString()) + TestState = { - TestState = + AdditionalFiles = { ("/0/Resources.resx", code) }, + AnalyzerConfigFiles = { - AdditionalFiles = { ("/0/Resources.resx", code) }, - AnalyzerConfigFiles = - { - ("/.globalconfig", $""" - is_global = true - - [/0/Resources.resx] - build_metadata.AdditionalFiles.AsConstants = {(asConstants ? "true" : "false")} - """), - }, + ("/.globalconfig", $""" + is_global = true + + [/0/Resources.resx] + build_metadata.AdditionalFiles.AsConstants = {(asConstants ? "true" : "false")} + """), }, - }.AddGeneratedSources().RunAsync(); - } + }, + }.AddGeneratedSources().RunAsync(); + } - [Theory] - [CombinatorialData] - public async Task SingleString_IncludeDefaultValuesCSharpAsync(bool includeDefaultValues) + [Theory] + [CombinatorialData] + public async Task SingleString_IncludeDefaultValuesCSharpAsync(bool includeDefaultValues) + { + var code = ResxHeader + + """ + + value + comment + + """ + + ResxFooter; + + await new VerifyCS.Test(identifier: includeDefaultValues.ToString()) { - var code = ResxHeader - + """ - - value - comment - - """ - + ResxFooter; - - await new VerifyCS.Test(identifier: includeDefaultValues.ToString()) + TestState = { - TestState = + AdditionalFiles = { ("/0/Resources.resx", code) }, + AnalyzerConfigFiles = { - AdditionalFiles = { ("/0/Resources.resx", code) }, - AnalyzerConfigFiles = - { - ("/.globalconfig", $""" - is_global = true - - [/0/Resources.resx] - build_metadata.AdditionalFiles.IncludeDefaultValues = {(includeDefaultValues ? "true" : "false")} - """), - }, + ("/.globalconfig", $""" + is_global = true + + [/0/Resources.resx] + build_metadata.AdditionalFiles.IncludeDefaultValues = {(includeDefaultValues ? "true" : "false")} + """), }, - }.AddGeneratedSources().RunAsync(); - } + }, + }.AddGeneratedSources().RunAsync(); + } - [Theory] - [CombinatorialData] - public async Task SingleString_IncludeDefaultValuesVisualBasicAsync(bool includeDefaultValues) + [Theory] + [CombinatorialData] + public async Task SingleString_IncludeDefaultValuesVisualBasicAsync(bool includeDefaultValues) + { + var code = ResxHeader + + """ + + value + comment + + """ + + ResxFooter; + + await new VerifyVB.Test(identifier: includeDefaultValues.ToString()) { - var code = ResxHeader - + """ - - value - comment - - """ - + ResxFooter; - - await new VerifyVB.Test(identifier: includeDefaultValues.ToString()) + TestState = { - TestState = + AdditionalFiles = { ("/0/Resources.resx", code) }, + AnalyzerConfigFiles = { - AdditionalFiles = { ("/0/Resources.resx", code) }, - AnalyzerConfigFiles = - { - ("/.globalconfig", $""" - is_global = true - - [/0/Resources.resx] - build_metadata.AdditionalFiles.IncludeDefaultValues = {(includeDefaultValues ? "true" : "false")} - """), - }, + ("/.globalconfig", $""" + is_global = true + + [/0/Resources.resx] + build_metadata.AdditionalFiles.IncludeDefaultValues = {(includeDefaultValues ? "true" : "false")} + """), }, - }.AddGeneratedSources().RunAsync(); - } - - [Theory] - [CombinatorialData] - public async Task SingleString_EmitFormatMethodsCSharpAsync( - [CombinatorialValues("0", "x", "replacement")] string placeholder, - bool emitFormatMethods) + }, + }.AddGeneratedSources().RunAsync(); + } + + [Theory] + [CombinatorialData] + public async Task SingleString_EmitFormatMethodsCSharpAsync( + [CombinatorialValues("0", "x", "replacement")] string placeholder, + bool emitFormatMethods) + { + var code = ResxHeader + + $$""" + + value {{{placeholder}}} + comment + + """ + + ResxFooter; + + await new VerifyCS.Test(identifier: $"{placeholder}_{emitFormatMethods}") { - var code = ResxHeader - + $$""" - - value {{{placeholder}}} - comment - - """ - + ResxFooter; - - await new VerifyCS.Test(identifier: $"{placeholder}_{emitFormatMethods}") + TestState = { - TestState = + AdditionalFiles = { ("/0/Resources.resx", code) }, + AnalyzerConfigFiles = { - AdditionalFiles = { ("/0/Resources.resx", code) }, - AnalyzerConfigFiles = - { - ("/.globalconfig", $""" - is_global = true - - [/0/Resources.resx] - build_metadata.AdditionalFiles.EmitFormatMethods = {(emitFormatMethods ? "true" : "false")} - """), - }, + ("/.globalconfig", $""" + is_global = true + + [/0/Resources.resx] + build_metadata.AdditionalFiles.EmitFormatMethods = {(emitFormatMethods ? "true" : "false")} + """), }, - }.AddGeneratedSources().RunAsync(); - } + }, + }.AddGeneratedSources().RunAsync(); + } - [Theory] - [InlineData(true, Skip = "Not yet supported")] - [InlineData(false)] - public async Task SingleString_EmitFormatMethodsVisualBasicAsync(bool emitFormatMethods) + [Theory] + [InlineData(true, Skip = "Not yet supported")] + [InlineData(false)] + public async Task SingleString_EmitFormatMethodsVisualBasicAsync(bool emitFormatMethods) + { + var code = ResxHeader + + """ + + value + comment + + """ + + ResxFooter; + + await new VerifyVB.Test(identifier: emitFormatMethods.ToString()) { - var code = ResxHeader - + """ - - value - comment - - """ - + ResxFooter; - - await new VerifyVB.Test(identifier: emitFormatMethods.ToString()) + TestState = { - TestState = + AdditionalFiles = { ("/0/Resources.resx", code) }, + AnalyzerConfigFiles = { - AdditionalFiles = { ("/0/Resources.resx", code) }, - AnalyzerConfigFiles = - { - ("/.globalconfig", $""" - is_global = true - - [/0/Resources.resx] - build_metadata.AdditionalFiles.EmitFormatMethods = {(emitFormatMethods ? "true" : "false")} - """), - }, + ("/.globalconfig", $""" + is_global = true + + [/0/Resources.resx] + build_metadata.AdditionalFiles.EmitFormatMethods = {(emitFormatMethods ? "true" : "false")} + """), }, - }.AddGeneratedSources().RunAsync(); - } + }, + }.AddGeneratedSources().RunAsync(); + } - [Theory] - [CombinatorialData] - public async Task SingleString_PublicCSharpAsync(bool publicResource) + [Theory] + [CombinatorialData] + public async Task SingleString_PublicCSharpAsync(bool publicResource) + { + var code = ResxHeader + + """ + + value + comment + + """ + + ResxFooter; + + await new VerifyCS.Test(identifier: publicResource.ToString()) { - var code = ResxHeader - + """ - - value - comment - - """ - + ResxFooter; - - await new VerifyCS.Test(identifier: publicResource.ToString()) + TestState = { - TestState = + AdditionalFiles = { ("/0/Resources.resx", code) }, + AnalyzerConfigFiles = { - AdditionalFiles = { ("/0/Resources.resx", code) }, - AnalyzerConfigFiles = - { - ("/.globalconfig", $""" - is_global = true - - [/0/Resources.resx] - build_metadata.AdditionalFiles.Public = {(publicResource ? "true" : "false")} - """), - }, + ("/.globalconfig", $""" + is_global = true + + [/0/Resources.resx] + build_metadata.AdditionalFiles.Public = {(publicResource ? "true" : "false")} + """), }, - }.AddGeneratedSources().RunAsync(); - } + }, + }.AddGeneratedSources().RunAsync(); + } - [Theory] - [CombinatorialData] - public async Task SingleString_PublicVisualBasicAsync(bool publicResource) + [Theory] + [CombinatorialData] + public async Task SingleString_PublicVisualBasicAsync(bool publicResource) + { + var code = ResxHeader + + """ + + value + comment + + """ + + ResxFooter; + + await new VerifyVB.Test(identifier: publicResource.ToString()) { - var code = ResxHeader - + """ - - value - comment - - """ - + ResxFooter; - - await new VerifyVB.Test(identifier: publicResource.ToString()) + TestState = { - TestState = + AdditionalFiles = { ("/0/Resources.resx", code) }, + AnalyzerConfigFiles = { - AdditionalFiles = { ("/0/Resources.resx", code) }, - AnalyzerConfigFiles = - { - ("/.globalconfig", $""" - is_global = true - - [/0/Resources.resx] - build_metadata.AdditionalFiles.Public = {(publicResource ? "true" : "false")} - """), - }, + ("/.globalconfig", $""" + is_global = true + + [/0/Resources.resx] + build_metadata.AdditionalFiles.Public = {(publicResource ? "true" : "false")} + """), }, - }.AddGeneratedSources().RunAsync(); - } - - [Theory] - [InlineData("")] - [InlineData("CS1591")] - [InlineData("CS1591, IDE0010")] - [InlineData(" , CS1591, IDE0010 ")] - public async Task SingleString_NoWarnsCSharpAsync(string noWarn) + }, + }.AddGeneratedSources().RunAsync(); + } + + [Theory] + [InlineData("")] + [InlineData("CS1591")] + [InlineData("CS1591, IDE0010")] + [InlineData(" , CS1591, IDE0010 ")] + public async Task SingleString_NoWarnsCSharpAsync(string noWarn) + { + var code = ResxHeader + + """ + + value + comment + + """ + + ResxFooter; + + var id = string.Join("_", noWarn.Replace(" ", "").Split(",", System.StringSplitOptions.TrimEntries | System.StringSplitOptions.RemoveEmptyEntries)); + + await new VerifyCS.Test(identifier: id) { - var code = ResxHeader - + """ - - value - comment - - """ - + ResxFooter; - - var id = string.Join("_", noWarn.Replace(" ", "").Split(",", System.StringSplitOptions.TrimEntries | System.StringSplitOptions.RemoveEmptyEntries)); - - await new VerifyCS.Test(identifier: id) + TestState = { - TestState = + AdditionalFiles = { ("/0/Resources.resx", code) }, + AnalyzerConfigFiles = { - AdditionalFiles = { ("/0/Resources.resx", code) }, - AnalyzerConfigFiles = - { - ("/.globalconfig", $""" - is_global = true - - [/0/Resources.resx] - build_metadata.AdditionalFiles.NoWarn = {noWarn} - """), - }, + ("/.globalconfig", $""" + is_global = true + + [/0/Resources.resx] + build_metadata.AdditionalFiles.NoWarn = {noWarn} + """), }, - }.AddGeneratedSources().RunAsync(); - } - - [Theory] - [InlineData("")] - [InlineData("CS1591")] - [InlineData("CS1591, IDE0010")] - [InlineData(" , CS1591, IDE0010 ")] - public async Task SingleString_NoWarnsVisualBasicAsync(string noWarn) + }, + }.AddGeneratedSources().RunAsync(); + } + + [Theory] + [InlineData("")] + [InlineData("CS1591")] + [InlineData("CS1591, IDE0010")] + [InlineData(" , CS1591, IDE0010 ")] + public async Task SingleString_NoWarnsVisualBasicAsync(string noWarn) + { + var code = ResxHeader + + """ + + value + comment + + """ + + ResxFooter; + + var id = string.Join("_", noWarn.Replace(" ", "").Split(",", System.StringSplitOptions.TrimEntries | System.StringSplitOptions.RemoveEmptyEntries)); + + await new VerifyVB.Test(identifier: id) { - var code = ResxHeader - + """ - - value - comment - - """ - + ResxFooter; - - var id = string.Join("_", noWarn.Replace(" ", "").Split(",", System.StringSplitOptions.TrimEntries | System.StringSplitOptions.RemoveEmptyEntries)); - - await new VerifyVB.Test(identifier: id) + TestState = { - TestState = + AdditionalFiles = { ("/0/Resources.resx", code) }, + AnalyzerConfigFiles = { - AdditionalFiles = { ("/0/Resources.resx", code) }, - AnalyzerConfigFiles = - { - ("/.globalconfig", $""" - is_global = true - - [/0/Resources.resx] - build_metadata.AdditionalFiles.NoWarn = {noWarn} - """), - }, + ("/.globalconfig", $""" + is_global = true + + [/0/Resources.resx] + build_metadata.AdditionalFiles.NoWarn = {noWarn} + """), }, - }.AddGeneratedSources().RunAsync(); - } + }, + }.AddGeneratedSources().RunAsync(); } } diff --git a/src/roslyn/src/RoslynAnalyzers/PerformanceSensitiveAnalyzers/UnitTests/AvoidAllocationWithArrayEmptyCodeFixTests.cs b/src/roslyn/src/RoslynAnalyzers/PerformanceSensitiveAnalyzers/UnitTests/AvoidAllocationWithArrayEmptyCodeFixTests.cs index 59a0985f90b..8554fb46947 100644 --- a/src/roslyn/src/RoslynAnalyzers/PerformanceSensitiveAnalyzers/UnitTests/AvoidAllocationWithArrayEmptyCodeFixTests.cs +++ b/src/roslyn/src/RoslynAnalyzers/PerformanceSensitiveAnalyzers/UnitTests/AvoidAllocationWithArrayEmptyCodeFixTests.cs @@ -3,513 +3,515 @@ // See the LICENSE file in the project root for more information. using System.Threading.Tasks; +using Microsoft.CodeAnalysis.CSharp.PerformanceSensitiveAnalyzers.CodeFixes; using Microsoft.CodeAnalysis.PerformanceSensitiveAnalyzers; +using Microsoft.CodeAnalysis.PerformanceSensitiveAnalyzers.UnitTests; using Xunit; -using VerifyCS = Microsoft.CodeAnalysis.PerformanceSensitiveAnalyzers.UnitTests.CSharpPerformanceCodeFixVerifier< - Microsoft.CodeAnalysis.PerformanceSensitiveAnalyzers.ExplicitAllocationAnalyzer, - Microsoft.CodeAnalysis.CSharp.PerformanceSensitiveAnalyzers.CodeFixes.AvoidAllocationWithArrayEmptyCodeFix>; -namespace Microsoft.CodeAnalysis.PerformanceSensitive.Analyzers.UnitTests +namespace Microsoft.CodeAnalysis.PerformanceSensitive.Analyzers.UnitTests; + +using VerifyCS = CSharpPerformanceCodeFixVerifier< + ExplicitAllocationAnalyzer, + AvoidAllocationWithArrayEmptyCodeFix>; + +public class AvoidAllocationWithArrayEmptyCodeFixTests { - public class AvoidAllocationWithArrayEmptyCodeFixTests - { - [Theory] - [InlineData("IEnumerable")] - [InlineData("IReadOnlyList")] - [InlineData("IReadOnlyCollection")] - public Task ShouldReplaceEmptyListCreationWithArrayEmptyWithReturnTypeAsync(string type) - => VerifyCS.VerifyCodeFixAsync($$""" - using System; - using System.Collections.Generic; - using Roslyn.Utilities; - - namespace SampleNamespace + [Theory] + [InlineData("IEnumerable")] + [InlineData("IReadOnlyList")] + [InlineData("IReadOnlyCollection")] + public Task ShouldReplaceEmptyListCreationWithArrayEmptyWithReturnTypeAsync(string type) + => VerifyCS.VerifyCodeFixAsync($$""" + using System; + using System.Collections.Generic; + using Roslyn.Utilities; + + namespace SampleNamespace + { + class SampleClass { - class SampleClass + [PerformanceSensitive("uri")] + public {{type}} DoSomething() { - [PerformanceSensitive("uri")] - public {{type}} DoSomething() - { - return new List(); - } + return new List(); } } - """, VerifyCS.Diagnostic(ExplicitAllocationAnalyzer.ObjectCreationRule).WithSpan(12, 20, 12, 35), $$""" - using System; - using System.Collections.Generic; - using Roslyn.Utilities; - - namespace SampleNamespace + } + """, VerifyCS.Diagnostic(ExplicitAllocationAnalyzer.ObjectCreationRule).WithSpan(12, 20, 12, 35), $$""" + using System; + using System.Collections.Generic; + using Roslyn.Utilities; + + namespace SampleNamespace + { + class SampleClass { - class SampleClass + [PerformanceSensitive("uri")] + public {{type}} DoSomething() { - [PerformanceSensitive("uri")] - public {{type}} DoSomething() - { - return Array.Empty(); - } + return Array.Empty(); } } - """); - - [Fact] - public Task ShouldReplaceEmptyListCreationWithArrayEmptyWhenReturnFromMethodArrayAsync() - => VerifyCS.VerifyCodeFixAsync(""" - using System; - using System.Collections.Generic; - using Roslyn.Utilities; - - namespace SampleNamespace + } + """); + + [Fact] + public Task ShouldReplaceEmptyListCreationWithArrayEmptyWhenReturnFromMethodArrayAsync() + => VerifyCS.VerifyCodeFixAsync(""" + using System; + using System.Collections.Generic; + using Roslyn.Utilities; + + namespace SampleNamespace + { + class SampleClass { - class SampleClass + [PerformanceSensitive("uri")] + public int[] DoSomething() { - [PerformanceSensitive("uri")] - public int[] DoSomething() - { - return new int[0]; - } + return new int[0]; } } - """, VerifyCS.Diagnostic(ExplicitAllocationAnalyzer.ArrayCreationRule).WithSpan(12, 20, 12, 30), """ - using System; - using System.Collections.Generic; - using Roslyn.Utilities; - - namespace SampleNamespace + } + """, VerifyCS.Diagnostic(ExplicitAllocationAnalyzer.ArrayCreationRule).WithSpan(12, 20, 12, 30), """ + using System; + using System.Collections.Generic; + using Roslyn.Utilities; + + namespace SampleNamespace + { + class SampleClass { - class SampleClass + [PerformanceSensitive("uri")] + public int[] DoSomething() { - [PerformanceSensitive("uri")] - public int[] DoSomething() - { - return Array.Empty(); - } + return Array.Empty(); } } - """); - - [Fact] - public Task ShouldReplaceEmptyLisCreationWithArrayEmptyForArrowExpressionAsync() - => VerifyCS.VerifyCodeFixAsync(""" - using System; - using System.Collections.Generic; - using Roslyn.Utilities; - - namespace SampleNamespace + } + """); + + [Fact] + public Task ShouldReplaceEmptyLisCreationWithArrayEmptyForArrowExpressionAsync() + => VerifyCS.VerifyCodeFixAsync(""" + using System; + using System.Collections.Generic; + using Roslyn.Utilities; + + namespace SampleNamespace + { + class SampleClass { - class SampleClass - { - [PerformanceSensitive("uri")] - public IEnumerable DoSomething => new List(); - } + [PerformanceSensitive("uri")] + public IEnumerable DoSomething => new List(); } - """, VerifyCS.Diagnostic(ExplicitAllocationAnalyzer.ObjectCreationRule).WithSpan(10, 48, 10, 63), """ - using System; - using System.Collections.Generic; - using Roslyn.Utilities; - - namespace SampleNamespace + } + """, VerifyCS.Diagnostic(ExplicitAllocationAnalyzer.ObjectCreationRule).WithSpan(10, 48, 10, 63), """ + using System; + using System.Collections.Generic; + using Roslyn.Utilities; + + namespace SampleNamespace + { + class SampleClass { - class SampleClass - { - [PerformanceSensitive("uri")] - public IEnumerable DoSomething => Array.Empty(); - } + [PerformanceSensitive("uri")] + public IEnumerable DoSomething => Array.Empty(); } - """); - [Fact] - public Task ShouldReplaceEmptyListCreationWithArrayEmptyForReadonlyPropertyAsync() - => VerifyCS.VerifyCodeFixAsync(""" - using System; - using System.Collections.Generic; - using Roslyn.Utilities; - - namespace SampleNamespace + } + """); + [Fact] + public Task ShouldReplaceEmptyListCreationWithArrayEmptyForReadonlyPropertyAsync() + => VerifyCS.VerifyCodeFixAsync(""" + using System; + using System.Collections.Generic; + using Roslyn.Utilities; + + namespace SampleNamespace + { + class SampleClass { - class SampleClass + [PerformanceSensitive("uri")] + public IEnumerable DoSomething { get {return new List();}} + } + } + """, VerifyCS.Diagnostic(ExplicitAllocationAnalyzer.ObjectCreationRule).WithSpan(10, 59, 10, 74), """ + using System; + using System.Collections.Generic; + using Roslyn.Utilities; + + namespace SampleNamespace + { + class SampleClass + { + [PerformanceSensitive("uri")] + public IEnumerable DoSomething { get {return Array.Empty();}} + } + } + """); + [Fact] + public Task ShouldReplaceEmptyListWithCreationWithPredefinedSizeWithArrayEmptyAsync() + => VerifyCS.VerifyCodeFixAsync(""" + using System; + using System.Collections.Generic; + using Roslyn.Utilities; + + namespace SampleNamespace + { + class SampleClass + { + [PerformanceSensitive("uri")] + public IEnumerable DoSomething() { - [PerformanceSensitive("uri")] - public IEnumerable DoSomething { get {return new List();}} + return new List(10); } } - """, VerifyCS.Diagnostic(ExplicitAllocationAnalyzer.ObjectCreationRule).WithSpan(10, 59, 10, 74), """ - using System; - using System.Collections.Generic; - using Roslyn.Utilities; - - namespace SampleNamespace + } + """, VerifyCS.Diagnostic(ExplicitAllocationAnalyzer.ObjectCreationRule).WithSpan(12, 20, 12, 37), """ + using System; + using System.Collections.Generic; + using Roslyn.Utilities; + + namespace SampleNamespace + { + class SampleClass { - class SampleClass + [PerformanceSensitive("uri")] + public IEnumerable DoSomething() { - [PerformanceSensitive("uri")] - public IEnumerable DoSomething { get {return Array.Empty();}} + return Array.Empty(); } } - """); - [Fact] - public Task ShouldReplaceEmptyListWithCreationWithPredefinedSizeWithArrayEmptyAsync() - => VerifyCS.VerifyCodeFixAsync(""" - using System; - using System.Collections.Generic; - using Roslyn.Utilities; - - namespace SampleNamespace + } + """); + [Fact] + public async Task ShouldNotProposeCodeFixWhenNonEmptyListCreatedAsync() + { + var code = """ + using System; + using System.Collections.Generic; + using Roslyn.Utilities; + + namespace SampleNamespace + { + class SampleClass { - class SampleClass + [PerformanceSensitive("uri")] + public IEnumerable DoSomething() { - [PerformanceSensitive("uri")] - public IEnumerable DoSomething() - { - return new List(10); - } + return new List(){1, 2}; } } - """, VerifyCS.Diagnostic(ExplicitAllocationAnalyzer.ObjectCreationRule).WithSpan(12, 20, 12, 37), """ - using System; - using System.Collections.Generic; - using Roslyn.Utilities; + } + """; - namespace SampleNamespace + await VerifyCS.VerifyCodeFixAsync(code, VerifyCS.Diagnostic(ExplicitAllocationAnalyzer.ObjectCreationRule).WithSpan(12, 20, 12, 41), code); + } + [Fact] + public async Task ShouldNotProposeCodeFixWhenReturnTypeInheritFormEnumerableAsync() + { + var code = """ + using System; + using System.Collections.Generic; + using Roslyn.Utilities; + + namespace SampleNamespace + { + class SampleClass { - class SampleClass + [PerformanceSensitive("uri")] + public List DoSomething() { - [PerformanceSensitive("uri")] - public IEnumerable DoSomething() - { - return Array.Empty(); - } + return new List(); } } - """); - [Fact] - public async Task ShouldNotProposeCodeFixWhenNonEmptyListCreatedAsync() - { - var code = """ - using System; - using System.Collections.Generic; - using Roslyn.Utilities; - - namespace SampleNamespace + } + """; + + await VerifyCS.VerifyCodeFixAsync(code, VerifyCS.Diagnostic(ExplicitAllocationAnalyzer.ObjectCreationRule).WithSpan(12, 20, 12, 35), code); + } + [Fact] + public async Task ShouldNotProposeCodeFixWhenForCollectionCreationUsingCopyConstructorAsync() + { + var code = """ + using System; + using System.Collections.Generic; + using System.Collections.ObjectModel; + using Roslyn.Utilities; + + namespace SampleNamespace + { + class SampleClass { - class SampleClass + [PerformanceSensitive("uri")] + public IEnumerable DoSomething() { - [PerformanceSensitive("uri")] - public IEnumerable DoSomething() - { - return new List(){1, 2}; - } + var innerList = new List(){1, 2}; + return new ReadOnlyCollection(innerList); } } - """; - - await VerifyCS.VerifyCodeFixAsync(code, VerifyCS.Diagnostic(ExplicitAllocationAnalyzer.ObjectCreationRule).WithSpan(12, 20, 12, 41), code); - } - [Fact] - public async Task ShouldNotProposeCodeFixWhenReturnTypeInheritFormEnumerableAsync() - { - var code = """ - using System; - using System.Collections.Generic; - using Roslyn.Utilities; - - namespace SampleNamespace + } + """; + + await VerifyCS.VerifyCodeFixAsync(code, + [ + VerifyCS.Diagnostic(ExplicitAllocationAnalyzer.ObjectCreationRule).WithSpan(13, 29, 13, 50), + VerifyCS.Diagnostic(ExplicitAllocationAnalyzer.ObjectCreationRule).WithSpan(14, 20, 14, 58), + ], code); + } + [Fact] + public Task ShouldReplacEmptyCollectionCreationWithArrayEmptyAsync() + => VerifyCS.VerifyCodeFixAsync(""" + using System; + using System.Collections.Generic; + using System.Collections.ObjectModel; + using Roslyn.Utilities; + + namespace SampleNamespace + { + class SampleClass { - class SampleClass + [PerformanceSensitive("uri")] + public IEnumerable DoSomething() { - [PerformanceSensitive("uri")] - public List DoSomething() - { - return new List(); - } + return new Collection(); } } - """; - - await VerifyCS.VerifyCodeFixAsync(code, VerifyCS.Diagnostic(ExplicitAllocationAnalyzer.ObjectCreationRule).WithSpan(12, 20, 12, 35), code); - } - [Fact] - public async Task ShouldNotProposeCodeFixWhenForCollectionCreationUsingCopyConstructorAsync() - { - var code = """ - using System; - using System.Collections.Generic; - using System.Collections.ObjectModel; - using Roslyn.Utilities; - - namespace SampleNamespace + } + """, VerifyCS.Diagnostic(ExplicitAllocationAnalyzer.ObjectCreationRule).WithSpan(13, 20, 13, 41), """ + using System; + using System.Collections.Generic; + using System.Collections.ObjectModel; + using Roslyn.Utilities; + + namespace SampleNamespace + { + class SampleClass { - class SampleClass + [PerformanceSensitive("uri")] + public IEnumerable DoSomething() { - [PerformanceSensitive("uri")] - public IEnumerable DoSomething() - { - var innerList = new List(){1, 2}; - return new ReadOnlyCollection(innerList); - } + return Array.Empty(); } } - """; - - await VerifyCS.VerifyCodeFixAsync(code, - [ - VerifyCS.Diagnostic(ExplicitAllocationAnalyzer.ObjectCreationRule).WithSpan(13, 29, 13, 50), - VerifyCS.Diagnostic(ExplicitAllocationAnalyzer.ObjectCreationRule).WithSpan(14, 20, 14, 58), - ], code); - } - [Fact] - public Task ShouldReplacEmptyCollectionCreationWithArrayEmptyAsync() - => VerifyCS.VerifyCodeFixAsync(""" - using System; - using System.Collections.Generic; - using System.Collections.ObjectModel; - using Roslyn.Utilities; - - namespace SampleNamespace + } + """); + [Fact] + public Task ShouldReplaceEmptyArrayCreationWithArrayEmptyAsync() + => VerifyCS.VerifyCodeFixAsync(""" + using System; + using System.Collections.Generic; + using Roslyn.Utilities; + + namespace SampleNamespace + { + class SampleClass { - class SampleClass + [PerformanceSensitive("uri")] + public IEnumerable DoSomething() { - [PerformanceSensitive("uri")] - public IEnumerable DoSomething() - { - return new Collection(); - } + return new int[0]; } } - """, VerifyCS.Diagnostic(ExplicitAllocationAnalyzer.ObjectCreationRule).WithSpan(13, 20, 13, 41), """ - using System; - using System.Collections.Generic; - using System.Collections.ObjectModel; - using Roslyn.Utilities; - - namespace SampleNamespace + } + """, VerifyCS.Diagnostic(ExplicitAllocationAnalyzer.ArrayCreationRule).WithSpan(12, 20, 12, 30), """ + using System; + using System.Collections.Generic; + using Roslyn.Utilities; + + namespace SampleNamespace + { + class SampleClass { - class SampleClass + [PerformanceSensitive("uri")] + public IEnumerable DoSomething() { - [PerformanceSensitive("uri")] - public IEnumerable DoSomething() - { - return Array.Empty(); - } + return Array.Empty(); } } - """); - [Fact] - public Task ShouldReplaceEmptyArrayCreationWithArrayEmptyAsync() - => VerifyCS.VerifyCodeFixAsync(""" - using System; - using System.Collections.Generic; - using Roslyn.Utilities; - - namespace SampleNamespace + } + """); + [Fact] + public async Task ShouldNotProposeCodeFixWhenNonEmptyArrayCreationAsync() + { + var code = """ + using System; + using System.Collections.Generic; + using Roslyn.Utilities; + + namespace SampleNamespace + { + class SampleClass { - class SampleClass + [PerformanceSensitive("uri")] + public IEnumerable DoSomething() { - [PerformanceSensitive("uri")] - public IEnumerable DoSomething() - { - return new int[0]; - } + return new int[]{1, 2}; } } - """, VerifyCS.Diagnostic(ExplicitAllocationAnalyzer.ArrayCreationRule).WithSpan(12, 20, 12, 30), """ - using System; - using System.Collections.Generic; - using Roslyn.Utilities; + } + """; - namespace SampleNamespace + await VerifyCS.VerifyCodeFixAsync(code, VerifyCS.Diagnostic(ExplicitAllocationAnalyzer.ArrayCreationRule).WithSpan(12, 20, 12, 35), code); + } + [Fact] + public Task ShouldReplaceEmptyArrayCreationWithInitBlockWithArrayEmptyAsync() + => VerifyCS.VerifyCodeFixAsync(""" + using System; + using System.Collections.Generic; + using Roslyn.Utilities; + + namespace SampleNamespace + { + class SampleClass { - class SampleClass + [PerformanceSensitive("uri")] + public IEnumerable DoSomething() { - [PerformanceSensitive("uri")] - public IEnumerable DoSomething() - { - return Array.Empty(); - } + return new int[] { }; } } - """); - [Fact] - public async Task ShouldNotProposeCodeFixWhenNonEmptyArrayCreationAsync() - { - var code = """ - using System; - using System.Collections.Generic; - using Roslyn.Utilities; - - namespace SampleNamespace + } + """, VerifyCS.Diagnostic(ExplicitAllocationAnalyzer.ArrayCreationRule).WithSpan(12, 20, 12, 33), """ + using System; + using System.Collections.Generic; + using Roslyn.Utilities; + + namespace SampleNamespace + { + class SampleClass { - class SampleClass + [PerformanceSensitive("uri")] + public IEnumerable DoSomething() { - [PerformanceSensitive("uri")] - public IEnumerable DoSomething() - { - return new int[]{1, 2}; - } + return Array.Empty(); } } - """; - - await VerifyCS.VerifyCodeFixAsync(code, VerifyCS.Diagnostic(ExplicitAllocationAnalyzer.ArrayCreationRule).WithSpan(12, 20, 12, 35), code); - } - [Fact] - public Task ShouldReplaceEmptyArrayCreationWithInitBlockWithArrayEmptyAsync() - => VerifyCS.VerifyCodeFixAsync(""" - using System; - using System.Collections.Generic; - using Roslyn.Utilities; - - namespace SampleNamespace + } + """); + [Fact] + public Task ShouldReplaceListCreationAsMethodInvocationParameterWithArrayEmptyAsync() + => VerifyCS.VerifyCodeFixAsync(""" + using System; + using System.Collections.Generic; + using Roslyn.Utilities; + + namespace SampleNamespace + { + class SampleClass { - class SampleClass + [PerformanceSensitive("uri")] + public void DoSomething() { - [PerformanceSensitive("uri")] - public IEnumerable DoSomething() - { - return new int[] { }; - } + Do(new List()); } - } - """, VerifyCS.Diagnostic(ExplicitAllocationAnalyzer.ArrayCreationRule).WithSpan(12, 20, 12, 33), """ - using System; - using System.Collections.Generic; - using Roslyn.Utilities; - namespace SampleNamespace - { - class SampleClass + private void Do(IEnumerable a) { - [PerformanceSensitive("uri")] - public IEnumerable DoSomething() - { - return Array.Empty(); - } + } } - """); - [Fact] - public Task ShouldReplaceListCreationAsMethodInvocationParameterWithArrayEmptyAsync() - => VerifyCS.VerifyCodeFixAsync(""" - using System; - using System.Collections.Generic; - using Roslyn.Utilities; - - namespace SampleNamespace + } + """, VerifyCS.Diagnostic(ExplicitAllocationAnalyzer.ObjectCreationRule).WithSpan(12, 16, 12, 31), """ + using System; + using System.Collections.Generic; + using Roslyn.Utilities; + + namespace SampleNamespace + { + class SampleClass { - class SampleClass + [PerformanceSensitive("uri")] + public void DoSomething() { - [PerformanceSensitive("uri")] - public void DoSomething() - { - Do(new List()); - } - - private void Do(IEnumerable a) - { - - } + Do(Array.Empty()); } - } - """, VerifyCS.Diagnostic(ExplicitAllocationAnalyzer.ObjectCreationRule).WithSpan(12, 16, 12, 31), """ - using System; - using System.Collections.Generic; - using Roslyn.Utilities; - namespace SampleNamespace - { - class SampleClass + private void Do(IEnumerable a) { - [PerformanceSensitive("uri")] - public void DoSomething() - { - Do(Array.Empty()); - } - private void Do(IEnumerable a) - { - - } } } - """); - [Fact] - public Task ShouldReplaceArrayCreationAsMethodInvocationParameterWithArrayEmptyAsync() - => VerifyCS.VerifyCodeFixAsync(""" - using System; - using System.Collections.Generic; - using Roslyn.Utilities; - - namespace SampleNamespace + } + """); + [Fact] + public Task ShouldReplaceArrayCreationAsMethodInvocationParameterWithArrayEmptyAsync() + => VerifyCS.VerifyCodeFixAsync(""" + using System; + using System.Collections.Generic; + using Roslyn.Utilities; + + namespace SampleNamespace + { + class SampleClass { - class SampleClass + [PerformanceSensitive("uri")] + public void DoSomething() { - [PerformanceSensitive("uri")] - public void DoSomething() - { - Do(new int[0]); - } + Do(new int[0]); + } - private void Do(IEnumerable a) - { + private void Do(IEnumerable a) + { - } } } - """, VerifyCS.Diagnostic(ExplicitAllocationAnalyzer.ArrayCreationRule).WithSpan(12, 16, 12, 26), """ - using System; - using System.Collections.Generic; - using Roslyn.Utilities; - - namespace SampleNamespace + } + """, VerifyCS.Diagnostic(ExplicitAllocationAnalyzer.ArrayCreationRule).WithSpan(12, 16, 12, 26), """ + using System; + using System.Collections.Generic; + using Roslyn.Utilities; + + namespace SampleNamespace + { + class SampleClass { - class SampleClass + [PerformanceSensitive("uri")] + public void DoSomething() { - [PerformanceSensitive("uri")] - public void DoSomething() - { - Do(Array.Empty()); - } + Do(Array.Empty()); + } - private void Do(IEnumerable a) - { + private void Do(IEnumerable a) + { - } } } - """); - [Fact] - public Task ShouldReplaceArrayCreationAsDelegateInvocationParameterWithArrayEmptyAsync() - => VerifyCS.VerifyCodeFixAsync(""" - using System; - using System.Collections.Generic; - using Roslyn.Utilities; - - namespace SampleNamespace + } + """); + [Fact] + public Task ShouldReplaceArrayCreationAsDelegateInvocationParameterWithArrayEmptyAsync() + => VerifyCS.VerifyCodeFixAsync(""" + using System; + using System.Collections.Generic; + using Roslyn.Utilities; + + namespace SampleNamespace + { + class SampleClass { - class SampleClass + [PerformanceSensitive("uri")] + public void DoSomething(Action> doSth) { - [PerformanceSensitive("uri")] - public void DoSomething(Action> doSth) - { - doSth(new int[0]); - } + doSth(new int[0]); } } - """, VerifyCS.Diagnostic(ExplicitAllocationAnalyzer.ArrayCreationRule).WithSpan(12, 19, 12, 29), """ - using System; - using System.Collections.Generic; - using Roslyn.Utilities; - - namespace SampleNamespace + } + """, VerifyCS.Diagnostic(ExplicitAllocationAnalyzer.ArrayCreationRule).WithSpan(12, 19, 12, 29), """ + using System; + using System.Collections.Generic; + using Roslyn.Utilities; + + namespace SampleNamespace + { + class SampleClass { - class SampleClass + [PerformanceSensitive("uri")] + public void DoSomething(Action> doSth) { - [PerformanceSensitive("uri")] - public void DoSomething(Action> doSth) - { - doSth(Array.Empty()); - } + doSth(Array.Empty()); } } - """); - } + } + """); } diff --git a/src/roslyn/src/RoslynAnalyzers/PerformanceSensitiveAnalyzers/UnitTests/CallSiteImplicitAllocationAnalyzerTests.cs b/src/roslyn/src/RoslynAnalyzers/PerformanceSensitiveAnalyzers/UnitTests/CallSiteImplicitAllocationAnalyzerTests.cs index bf22e1b99b7..5ed95490694 100644 --- a/src/roslyn/src/RoslynAnalyzers/PerformanceSensitiveAnalyzers/UnitTests/CallSiteImplicitAllocationAnalyzerTests.cs +++ b/src/roslyn/src/RoslynAnalyzers/PerformanceSensitiveAnalyzers/UnitTests/CallSiteImplicitAllocationAnalyzerTests.cs @@ -4,203 +4,204 @@ using System.Threading.Tasks; using Microsoft.CodeAnalysis.CSharp.PerformanceSensitiveAnalyzers; +using Microsoft.CodeAnalysis.PerformanceSensitiveAnalyzers.UnitTests; using Microsoft.CodeAnalysis.Testing; using Test.Utilities; using Xunit; -using VerifyCS = Microsoft.CodeAnalysis.PerformanceSensitiveAnalyzers.UnitTests.CSharpPerformanceCodeFixVerifier< - Microsoft.CodeAnalysis.CSharp.PerformanceSensitiveAnalyzers.CallSiteImplicitAllocationAnalyzer, - Microsoft.CodeAnalysis.Testing.EmptyCodeFixProvider>; -namespace Microsoft.CodeAnalysisPerformanceSensitiveAnalyzers.UnitTests +namespace Microsoft.CodeAnalysisPerformanceSensitiveAnalyzers.UnitTests; + +using VerifyCS = CSharpPerformanceCodeFixVerifier< + CallSiteImplicitAllocationAnalyzer, + EmptyCodeFixProvider>; + +public sealed class CallSiteImplicitAllocationAnalyzerTests { - public class CallSiteImplicitAllocationAnalyzerTests - { - [Fact] - public Task CallSiteImplicitAllocation_ParamAsync() - => VerifyCS.VerifyAnalyzerAsync(""" - using System; - using Roslyn.Utilities; - - public class MyClass + [Fact] + public Task CallSiteImplicitAllocation_ParamAsync() + => VerifyCS.VerifyAnalyzerAsync(""" + using System; + using Roslyn.Utilities; + + public class MyClass + { + [PerformanceSensitive("uri")] + public void Testing() { - [PerformanceSensitive("uri")] - public void Testing() - { - Params(); //no allocation, because compiler will implicitly substitute Array.Empty() - Params(1, 2); - Params(new [] { 1, 2}); // explicit, so no warning - ParamsWithObjects(new [] { 1, 2}); // explicit, but converted to objects, so stil la warning?! + Params(); //no allocation, because compiler will implicitly substitute Array.Empty() + Params(1, 2); + Params(new [] { 1, 2}); // explicit, so no warning + ParamsWithObjects(new [] { 1, 2}); // explicit, but converted to objects, so stil la warning?! - // Only 4 args and above use the params overload of String.Format - var test = String.Format("Testing {0}, {1}, {2}, {3}", 1, "blah", 2.0m, 'c'); - } + // Only 4 args and above use the params overload of String.Format + var test = String.Format("Testing {0}, {1}, {2}, {3}", 1, "blah", 2.0m, 'c'); + } - public void Params(params int[] args) - { - } + public void Params(params int[] args) + { + } - public void ParamsWithObjects(params object[] args) - { - } + public void ParamsWithObjects(params object[] args) + { } - """, - // Test0.cs(11,9): warning HAA0101: This call site is calling into a function with a 'params' parameter. This results in an array allocation + } + """, + // Test0.cs(11,9): warning HAA0101: This call site is calling into a function with a 'params' parameter. This results in an array allocation #pragma warning disable RS0030 // Do not use banned APIs - VerifyCS.Diagnostic(CallSiteImplicitAllocationAnalyzer.ParamsParameterRule).WithLocation(11, 9), + VerifyCS.Diagnostic(CallSiteImplicitAllocationAnalyzer.ParamsParameterRule).WithLocation(11, 9), #pragma warning restore RS0030 // Do not use banned APIs - // Test0.cs(13,9): warning HAA0101: This call site is calling into a function with a 'params' parameter. This results in an array allocation + // Test0.cs(13,9): warning HAA0101: This call site is calling into a function with a 'params' parameter. This results in an array allocation #pragma warning disable RS0030 // Do not use banned APIs - VerifyCS.Diagnostic(CallSiteImplicitAllocationAnalyzer.ParamsParameterRule).WithLocation(13, 9), + VerifyCS.Diagnostic(CallSiteImplicitAllocationAnalyzer.ParamsParameterRule).WithLocation(13, 9), #pragma warning restore RS0030 // Do not use banned APIs - // Test0.cs(16,20): warning HAA0101: This call site is calling into a function with a 'params' parameter. This results in an array allocation + // Test0.cs(16,20): warning HAA0101: This call site is calling into a function with a 'params' parameter. This results in an array allocation #pragma warning disable RS0030 // Do not use banned APIs - VerifyCS.Diagnostic(CallSiteImplicitAllocationAnalyzer.ParamsParameterRule).WithLocation(16, 20)); - - [Fact, WorkItem(3272, "https://github.com/dotnet/roslyn-analyzers/issues/3272")] - public Task EmptyParamsWithNetFramework45Async() - => new VerifyCS.Test + VerifyCS.Diagnostic(CallSiteImplicitAllocationAnalyzer.ParamsParameterRule).WithLocation(16, 20)); + + [Fact, WorkItem(3272, "https://github.com/dotnet/roslyn-analyzers/issues/3272")] + public Task EmptyParamsWithNetFramework45Async() + => new VerifyCS.Test + { + ReferenceAssemblies = ReferenceAssemblies.NetFramework.Net45.Default, + TestState = { - ReferenceAssemblies = ReferenceAssemblies.NetFramework.Net45.Default, - TestState = + Sources = { - Sources = + """ + using System; + using Roslyn.Utilities; + + public class MyClass { - """ - using System; - using Roslyn.Utilities; + [PerformanceSensitive("uri")] + public void Testing() + { + Params(); // allocation + } - public class MyClass + public void Params(params int[] args) { - [PerformanceSensitive("uri")] - public void Testing() - { - Params(); // allocation - } - - public void Params(params int[] args) - { - } } - """, - ("PerformanceSensitiveAttribute.cs", VerifyCS.PerformanceSensitiveAttributeSource) - }, - ExpectedDiagnostics = - { + } + """, + ("PerformanceSensitiveAttribute.cs", VerifyCS.PerformanceSensitiveAttributeSource) + }, + ExpectedDiagnostics = + { #pragma warning disable RS0030 // Do not use banned APIs - VerifyCS.Diagnostic(CallSiteImplicitAllocationAnalyzer.ParamsParameterRule).WithLocation(9, 9), + VerifyCS.Diagnostic(CallSiteImplicitAllocationAnalyzer.ParamsParameterRule).WithLocation(9, 9), #pragma warning restore RS0030 // Do not use banned APIs - }, }, - }.RunAsync(); + }, + }.RunAsync(); - [Fact] - public Task CallSiteImplicitAllocation_NonOverridenMethodOnStructAsync() - => VerifyCS.VerifyAnalyzerAsync(""" - using System; - using Roslyn.Utilities; + [Fact] + public Task CallSiteImplicitAllocation_NonOverridenMethodOnStructAsync() + => VerifyCS.VerifyAnalyzerAsync(""" + using System; + using Roslyn.Utilities; - public class MyClass + public class MyClass + { + [PerformanceSensitive("uri")] + public void Testing() { - [PerformanceSensitive("uri")] - public void Testing() - { - var normal = new Normal().GetHashCode(); - var overridden = new OverrideToHashCode().GetHashCode(); - } + var normal = new Normal().GetHashCode(); + var overridden = new OverrideToHashCode().GetHashCode(); } + } - public struct Normal - { - } + public struct Normal + { + } - public struct OverrideToHashCode + public struct OverrideToHashCode + { + public override int GetHashCode() { - public override int GetHashCode() - { - return -1; - } + return -1; } - """, - // Test0.cs(10,22): warning HAA0102: Non-overridden virtual method call on a value type adds a boxing or constrained instruction + } + """, + // Test0.cs(10,22): warning HAA0102: Non-overridden virtual method call on a value type adds a boxing or constrained instruction #pragma warning disable RS0030 // Do not use banned APIs - VerifyCS.Diagnostic(CallSiteImplicitAllocationAnalyzer.ValueTypeNonOverridenCallRule).WithLocation(9, 22)); + VerifyCS.Diagnostic(CallSiteImplicitAllocationAnalyzer.ValueTypeNonOverridenCallRule).WithLocation(9, 22)); - [Fact] - public Task CallSiteImplicitAllocation_DoNotReportNonOverriddenMethodCallForStaticCallsAsync() - => VerifyCS.VerifyAnalyzerAsync(""" - using System; - using Roslyn.Utilities; + [Fact] + public Task CallSiteImplicitAllocation_DoNotReportNonOverriddenMethodCallForStaticCallsAsync() + => VerifyCS.VerifyAnalyzerAsync(""" + using System; + using Roslyn.Utilities; - public class MyClass + public class MyClass + { + [PerformanceSensitive("uri")] + public void Testing() { - [PerformanceSensitive("uri")] - public void Testing() - { - var t = System.Enum.GetUnderlyingType(typeof(System.StringComparison)); - } + var t = System.Enum.GetUnderlyingType(typeof(System.StringComparison)); } - """); + } + """); - [Fact] - public Task CallSiteImplicitAllocation_DoNotReportNonOverriddenMethodCallForNonVirtualCallsAsync() - => VerifyCS.VerifyAnalyzerAsync(""" - using System.IO; - using Roslyn.Utilities; + [Fact] + public Task CallSiteImplicitAllocation_DoNotReportNonOverriddenMethodCallForNonVirtualCallsAsync() + => VerifyCS.VerifyAnalyzerAsync(""" + using System.IO; + using Roslyn.Utilities; - public class MyClass + public class MyClass + { + [PerformanceSensitive("uri")] + public void Testing() { - [PerformanceSensitive("uri")] - public void Testing() - { - FileAttributes attr = FileAttributes.System; - attr.HasFlag (FileAttributes.Directory); - } + FileAttributes attr = FileAttributes.System; + attr.HasFlag (FileAttributes.Directory); } - """); + } + """); - [Fact] - public Task ParamsIsPrecededByOptionalParametersAsync() - => VerifyCS.VerifyAnalyzerAsync(""" - using System.IO; - using Roslyn.Utilities; + [Fact] + public Task ParamsIsPrecededByOptionalParametersAsync() + => VerifyCS.VerifyAnalyzerAsync(""" + using System.IO; + using Roslyn.Utilities; - public class MyClass + public class MyClass + { + [PerformanceSensitive("uri")] + void Fun1() { - [PerformanceSensitive("uri")] - void Fun1() - { - Fun2(); - {|#0:Fun2(args: "", i: 5)|}; - } + Fun2(); + {|#0:Fun2(args: "", i: 5)|}; + } - void Fun2(int i = 0, params object[] args) - { - } + void Fun2(int i = 0, params object[] args) + { } - """, - VerifyCS.Diagnostic(CallSiteImplicitAllocationAnalyzer.ParamsParameterRule).WithLocation(0)); + } + """, + VerifyCS.Diagnostic(CallSiteImplicitAllocationAnalyzer.ParamsParameterRule).WithLocation(0)); - [Fact] - [WorkItem(7995606, "http://stackoverflow.com/questions/7995606/boxing-occurrence-in-c-sharp")] - public Task Calling_non_overridden_virtual_methods_on_value_typesAsync() - => VerifyCS.VerifyAnalyzerAsync(""" - using System; - using Roslyn.Utilities; + [Fact] + [WorkItem(7995606, "http://stackoverflow.com/questions/7995606/boxing-occurrence-in-c-sharp")] + public Task Calling_non_overridden_virtual_methods_on_value_typesAsync() + => VerifyCS.VerifyAnalyzerAsync(""" + using System; + using Roslyn.Utilities; - enum E { A } + enum E { A } - public class MyClass + public class MyClass + { + [PerformanceSensitive("uri")] + public void SomeMethod() { - [PerformanceSensitive("uri")] - public void SomeMethod() - { - E.A.GetHashCode(); - } + E.A.GetHashCode(); } - """, - // Test0.cs(12,9): warning HAA0102: Non-overridden virtual method call on a value type adds a boxing or constrained instruction + } + """, + // Test0.cs(12,9): warning HAA0102: Non-overridden virtual method call on a value type adds a boxing or constrained instruction #pragma warning disable RS0030 // Do not use banned APIs - VerifyCS.Diagnostic(CallSiteImplicitAllocationAnalyzer.ValueTypeNonOverridenCallRule).WithLocation(11, 9)); - } + VerifyCS.Diagnostic(CallSiteImplicitAllocationAnalyzer.ValueTypeNonOverridenCallRule).WithLocation(11, 9)); } diff --git a/src/roslyn/src/RoslynAnalyzers/PerformanceSensitiveAnalyzers/UnitTests/ConcatenationAllocationAnalyzerTests.cs b/src/roslyn/src/RoslynAnalyzers/PerformanceSensitiveAnalyzers/UnitTests/ConcatenationAllocationAnalyzerTests.cs index 98e7c045bd1..680e1420ebb 100644 --- a/src/roslyn/src/RoslynAnalyzers/PerformanceSensitiveAnalyzers/UnitTests/ConcatenationAllocationAnalyzerTests.cs +++ b/src/roslyn/src/RoslynAnalyzers/PerformanceSensitiveAnalyzers/UnitTests/ConcatenationAllocationAnalyzerTests.cs @@ -4,110 +4,111 @@ using System.Threading.Tasks; using Microsoft.CodeAnalysis.CSharp.PerformanceSensitiveAnalyzers; +using Microsoft.CodeAnalysis.Testing; using Test.Utilities; using Xunit; -using VerifyCS = Microsoft.CodeAnalysis.PerformanceSensitiveAnalyzers.UnitTests.CSharpPerformanceCodeFixVerifier< - Microsoft.CodeAnalysis.CSharp.PerformanceSensitiveAnalyzers.ConcatenationAllocationAnalyzer, - Microsoft.CodeAnalysis.Testing.EmptyCodeFixProvider>; -namespace Microsoft.CodeAnalysis.PerformanceSensitiveAnalyzers.UnitTests +namespace Microsoft.CodeAnalysis.PerformanceSensitiveAnalyzers.UnitTests; + +using VerifyCS = CSharpPerformanceCodeFixVerifier< + ConcatenationAllocationAnalyzer, + EmptyCodeFixProvider>; + +public sealed class ConcatenationAllocationAnalyzerTests { - public class ConcatenationAllocationAnalyzerTests - { - [Fact] - public Task ConcatenationAllocation_Basic1Async() - => VerifyCS.VerifyAnalyzerAsync(""" - using System; - using Roslyn.Utilities; + [Fact] + public Task ConcatenationAllocation_Basic1Async() + => VerifyCS.VerifyAnalyzerAsync(""" + using System; + using Roslyn.Utilities; - public class MyClass + public class MyClass + { + [PerformanceSensitive("uri")] + public void Testing() { - [PerformanceSensitive("uri")] - public void Testing() - { - string s0 = "hello" + 0.ToString() + "world" + 1.ToString(); - } + string s0 = "hello" + 0.ToString() + "world" + 1.ToString(); } - """); + } + """); - [Fact] - public Task ConcatenationAllocation_Basic2Async() - => VerifyCS.VerifyAnalyzerAsync(""" - using System; - using Roslyn.Utilities; + [Fact] + public Task ConcatenationAllocation_Basic2Async() + => VerifyCS.VerifyAnalyzerAsync(""" + using System; + using Roslyn.Utilities; - public class MyClass + public class MyClass + { + [PerformanceSensitive("uri")] + public void Testing() { - [PerformanceSensitive("uri")] - public void Testing() - { - string s2 = "ohell" + 2.ToString() + "world" + 3.ToString() + 4.ToString(); - } + string s2 = "ohell" + 2.ToString() + "world" + 3.ToString() + 4.ToString(); } - """, - // Test0.cs(9,21): warning HAA0201: Considering using StringBuilder + } + """, + // Test0.cs(9,21): warning HAA0201: Considering using StringBuilder #pragma warning disable RS0030 // Do not use banned APIs - VerifyCS.Diagnostic(ConcatenationAllocationAnalyzer.StringConcatenationAllocationRule).WithLocation(9, 21)); + VerifyCS.Diagnostic(ConcatenationAllocationAnalyzer.StringConcatenationAllocationRule).WithLocation(9, 21)); - [Theory] - [InlineData("string s0 = nameof(System.String) + '-';")] - [InlineData("string s0 = nameof(System.String) + true;")] - [InlineData("string s0 = nameof(System.String) + new System.IntPtr();")] - [InlineData("string s0 = nameof(System.String) + new System.UIntPtr();")] - public Task ConcatenationAllocation_DoNotWarnForOptimizedValueTypesAsync(string statement) - => VerifyCS.VerifyAnalyzerAsync($$""" - using System; - using Roslyn.Utilities; + [Theory] + [InlineData("string s0 = nameof(System.String) + '-';")] + [InlineData("string s0 = nameof(System.String) + true;")] + [InlineData("string s0 = nameof(System.String) + new System.IntPtr();")] + [InlineData("string s0 = nameof(System.String) + new System.UIntPtr();")] + public Task ConcatenationAllocation_DoNotWarnForOptimizedValueTypesAsync(string statement) + => VerifyCS.VerifyAnalyzerAsync($$""" + using System; + using Roslyn.Utilities; - public class MyClass + public class MyClass + { + [PerformanceSensitive("uri")] + public void Testing() { - [PerformanceSensitive("uri")] - public void Testing() - { - {{statement}} - } + {{statement}} } - """); + } + """); - [Theory] - [InlineData(@"const string s0 = nameof(System.String) + ""."" + nameof(System.String);")] - [InlineData(@"const string s0 = nameof(System.String) + ""."";")] - [InlineData(@"string s0 = nameof(System.String) + ""."" + nameof(System.String);")] - [InlineData(@"string s0 = nameof(System.String) + ""."";")] - public Task ConcatenationAllocation_DoNotWarnForConstAsync(string statement) - => VerifyCS.VerifyAnalyzerAsync($$""" - using System; - using Roslyn.Utilities; + [Theory] + [InlineData(@"const string s0 = nameof(System.String) + ""."" + nameof(System.String);")] + [InlineData(@"const string s0 = nameof(System.String) + ""."";")] + [InlineData(@"string s0 = nameof(System.String) + ""."" + nameof(System.String);")] + [InlineData(@"string s0 = nameof(System.String) + ""."";")] + public Task ConcatenationAllocation_DoNotWarnForConstAsync(string statement) + => VerifyCS.VerifyAnalyzerAsync($$""" + using System; + using Roslyn.Utilities; - public class MyClass + public class MyClass + { + [PerformanceSensitive("uri")] + public void Testing() { - [PerformanceSensitive("uri")] - public void Testing() - { - {{statement}} - } + {{statement}} } - """); + } + """); - [Fact] - [WorkItem(7995606, "http://stackoverflow.com/questions/7995606/boxing-occurrence-in-c-sharp")] - public Task Non_constant_value_types_in_CSharp_string_concatenationAsync() - => VerifyCS.VerifyAnalyzerAsync(""" - using System; - using Roslyn.Utilities; + [Fact] + [WorkItem(7995606, "http://stackoverflow.com/questions/7995606/boxing-occurrence-in-c-sharp")] + public Task Non_constant_value_types_in_CSharp_string_concatenationAsync() + => VerifyCS.VerifyAnalyzerAsync(""" + using System; + using Roslyn.Utilities; - public class MyClass + public class MyClass + { + [PerformanceSensitive("uri")] + public void SomeMethod() { - [PerformanceSensitive("uri")] - public void SomeMethod() - { - System.DateTime c = System.DateTime.Now; - string s1 = "char value will box" + c; - } + System.DateTime c = System.DateTime.Now; + string s1 = "char value will box" + c; } - """, - // Test0.cs(11,45): warning HAA0202: Value type (System.DateTime) is being boxed to a reference type for a string concatenation. + } + """, + // Test0.cs(11,45): warning HAA0202: Value type (System.DateTime) is being boxed to a reference type for a string concatenation. #pragma warning disable RS0030 // Do not use banned APIs - VerifyCS.Diagnostic(ConcatenationAllocationAnalyzer.ValueTypeToReferenceTypeInAStringConcatenationRule).WithLocation(10, 45).WithArguments("System.DateTime")); - } + VerifyCS.Diagnostic(ConcatenationAllocationAnalyzer.ValueTypeToReferenceTypeInAStringConcatenationRule).WithLocation(10, 45).WithArguments("System.DateTime")); } diff --git a/src/roslyn/src/RoslynAnalyzers/PerformanceSensitiveAnalyzers/UnitTests/DisplayClassAllocationAnalyzerTests.cs b/src/roslyn/src/RoslynAnalyzers/PerformanceSensitiveAnalyzers/UnitTests/DisplayClassAllocationAnalyzerTests.cs index 62f1fae06db..8c0f431e85a 100644 --- a/src/roslyn/src/RoslynAnalyzers/PerformanceSensitiveAnalyzers/UnitTests/DisplayClassAllocationAnalyzerTests.cs +++ b/src/roslyn/src/RoslynAnalyzers/PerformanceSensitiveAnalyzers/UnitTests/DisplayClassAllocationAnalyzerTests.cs @@ -4,164 +4,166 @@ using System.Threading.Tasks; using Microsoft.CodeAnalysis.CSharp.PerformanceSensitiveAnalyzers; +using Microsoft.CodeAnalysis.PerformanceSensitiveAnalyzers.UnitTests; +using Microsoft.CodeAnalysis.Testing; using Xunit; -using VerifyCS = Microsoft.CodeAnalysis.PerformanceSensitiveAnalyzers.UnitTests.CSharpPerformanceCodeFixVerifier< - Microsoft.CodeAnalysis.CSharp.PerformanceSensitiveAnalyzers.DisplayClassAllocationAnalyzer, - Microsoft.CodeAnalysis.Testing.EmptyCodeFixProvider>; -namespace Microsoft.CodeAnalysis.PerformanceSensitive.Analyzers.UnitTests +namespace Microsoft.CodeAnalysis.PerformanceSensitive.Analyzers.UnitTests; + +using VerifyCS = CSharpPerformanceCodeFixVerifier< + DisplayClassAllocationAnalyzer, + EmptyCodeFixProvider>; + +public sealed class DisplayClassAllocationAnalyzerTests { - public class DisplayClassAllocationAnalyzerTests - { - [Fact] - public Task DisplayClassAllocation_AnonymousMethodExpressionSyntaxAsync() - => VerifyCS.VerifyAnalyzerAsync(""" - using System; - using Roslyn.Utilities; - - class Test + [Fact] + public Task DisplayClassAllocation_AnonymousMethodExpressionSyntaxAsync() + => VerifyCS.VerifyAnalyzerAsync(""" + using System; + using Roslyn.Utilities; + + class Test + { + static void Main() { - static void Main() - { - Action action = CreateAction(5); - } + Action action = CreateAction(5); + } - [PerformanceSensitive("uri")] - static Action CreateAction(T item) + [PerformanceSensitive("uri")] + static Action CreateAction(T item) + { + T test = default(T); + int counter = 0; + return delegate { - T test = default(T); - int counter = 0; - return delegate - { - counter++; - Console.WriteLine("counter={0}", counter); - }; - } + counter++; + Console.WriteLine("counter={0}", counter); + }; } - """, - // Test0.cs(15,13): warning HAA0302: The compiler will emit a class that will hold this as a field to allow capturing of this closure + } + """, + // Test0.cs(15,13): warning HAA0302: The compiler will emit a class that will hold this as a field to allow capturing of this closure #pragma warning disable RS0030 // Do not use banned APIs - VerifyCS.Diagnostic(DisplayClassAllocationAnalyzer.ClosureCaptureRule).WithLocation(15, 13), + VerifyCS.Diagnostic(DisplayClassAllocationAnalyzer.ClosureCaptureRule).WithLocation(15, 13), #pragma warning restore RS0030 // Do not use banned APIs - // Test0.cs(16,16): warning HAA0303: Considering moving this out of the generic method + // Test0.cs(16,16): warning HAA0303: Considering moving this out of the generic method #pragma warning disable RS0030 // Do not use banned APIs - VerifyCS.Diagnostic(DisplayClassAllocationAnalyzer.LambaOrAnonymousMethodInGenericMethodRule).WithLocation(16, 16), + VerifyCS.Diagnostic(DisplayClassAllocationAnalyzer.LambaOrAnonymousMethodInGenericMethodRule).WithLocation(16, 16), #pragma warning restore RS0030 // Do not use banned APIs - // Test0.cs(16,16): warning HAA0301: Heap allocation of closure Captures: counter + // Test0.cs(16,16): warning HAA0301: Heap allocation of closure Captures: counter #pragma warning disable RS0030 // Do not use banned APIs - VerifyCS.Diagnostic(DisplayClassAllocationAnalyzer.ClosureDriverRule).WithLocation(16, 16).WithArguments("counter")); + VerifyCS.Diagnostic(DisplayClassAllocationAnalyzer.ClosureDriverRule).WithLocation(16, 16).WithArguments("counter")); - [Fact] - public Task DisplayClassAllocation_SimpleLambdaExpressionSyntaxAsync() - => VerifyCS.VerifyAnalyzerAsync(""" - using System.Collections.Generic; - using System; - using System.Linq; - using Roslyn.Utilities; + [Fact] + public Task DisplayClassAllocation_SimpleLambdaExpressionSyntaxAsync() + => VerifyCS.VerifyAnalyzerAsync(""" + using System.Collections.Generic; + using System; + using System.Linq; + using Roslyn.Utilities; - public class Testing + public class Testing + { + [PerformanceSensitive("uri")] + public Testing() { - [PerformanceSensitive("uri")] - public Testing() - { - int[] intData = new[] { 123, 32, 4 }; - int min = 31; - var results = intData.Where(i => i > min).ToList(); - } + int[] intData = new[] { 123, 32, 4 }; + int min = 31; + var results = intData.Where(i => i > min).ToList(); } - """, - // Test0.cs(12,13): warning HAA0302: The compiler will emit a class that will hold this as a field to allow capturing of this closure + } + """, + // Test0.cs(12,13): warning HAA0302: The compiler will emit a class that will hold this as a field to allow capturing of this closure #pragma warning disable RS0030 // Do not use banned APIs - VerifyCS.Diagnostic(DisplayClassAllocationAnalyzer.ClosureCaptureRule).WithLocation(12, 13), + VerifyCS.Diagnostic(DisplayClassAllocationAnalyzer.ClosureCaptureRule).WithLocation(12, 13), #pragma warning restore RS0030 // Do not use banned APIs - // Test0.cs(13,39): warning HAA0301: Heap allocation of closure Captures: min + // Test0.cs(13,39): warning HAA0301: Heap allocation of closure Captures: min #pragma warning disable RS0030 // Do not use banned APIs - VerifyCS.Diagnostic(DisplayClassAllocationAnalyzer.ClosureDriverRule).WithLocation(13, 39).WithArguments("min")); + VerifyCS.Diagnostic(DisplayClassAllocationAnalyzer.ClosureDriverRule).WithLocation(13, 39).WithArguments("min")); - [Fact] - public Task DisplayClassAllocation_ParenthesizedLambdaExpressionSyntaxAsync() - => VerifyCS.VerifyAnalyzerAsync(""" - using System.Collections.Generic; - using System; - using System.Linq; - using Roslyn.Utilities; + [Fact] + public Task DisplayClassAllocation_ParenthesizedLambdaExpressionSyntaxAsync() + => VerifyCS.VerifyAnalyzerAsync(""" + using System.Collections.Generic; + using System; + using System.Linq; + using Roslyn.Utilities; - public class MyClass + public class MyClass + { + [PerformanceSensitive("uri")] + public void SomeMethod() { - [PerformanceSensitive("uri")] - public void SomeMethod() + var words = new[] { "aaaa", "bbbb", "cccc", "ddd" }; + var actions = new List(); + foreach (string word in words) // <-- captured closure { - var words = new[] { "aaaa", "bbbb", "cccc", "ddd" }; - var actions = new List(); - foreach (string word in words) // <-- captured closure - { - actions.Add(() => Console.WriteLine(word)); // <-- reason for closure capture - } + actions.Add(() => Console.WriteLine(word)); // <-- reason for closure capture } } - """, - // Test0.cs(13,25): warning HAA0302: The compiler will emit a class that will hold this as a field to allow capturing of this closure + } + """, + // Test0.cs(13,25): warning HAA0302: The compiler will emit a class that will hold this as a field to allow capturing of this closure #pragma warning disable RS0030 // Do not use banned APIs - VerifyCS.Diagnostic(DisplayClassAllocationAnalyzer.ClosureCaptureRule).WithLocation(13, 25), + VerifyCS.Diagnostic(DisplayClassAllocationAnalyzer.ClosureCaptureRule).WithLocation(13, 25), #pragma warning restore RS0030 // Do not use banned APIs - // Test0.cs(15,28): warning HAA0301: Heap allocation of closure Captures: word + // Test0.cs(15,28): warning HAA0301: Heap allocation of closure Captures: word #pragma warning disable RS0030 // Do not use banned APIs - VerifyCS.Diagnostic(DisplayClassAllocationAnalyzer.ClosureDriverRule).WithLocation(15, 28).WithArguments("word")); + VerifyCS.Diagnostic(DisplayClassAllocationAnalyzer.ClosureDriverRule).WithLocation(15, 28).WithArguments("word")); - [Fact] - public Task DisplayClassAllocation_DoNotReportForNonCapturingAnonymousMethodAsync() - => VerifyCS.VerifyAnalyzerAsync(""" - using System; - using Roslyn.Utilities; + [Fact] + public Task DisplayClassAllocation_DoNotReportForNonCapturingAnonymousMethodAsync() + => VerifyCS.VerifyAnalyzerAsync(""" + using System; + using Roslyn.Utilities; - public class MyClass + public class MyClass + { + [PerformanceSensitive("uri")] + public void Sorter(int[] arr) { - [PerformanceSensitive("uri")] - public void Sorter(int[] arr) - { - System.Array.Sort(arr, delegate(int x, int y) { return x - y; }); - } + System.Array.Sort(arr, delegate(int x, int y) { return x - y; }); } - """); + } + """); - [Fact] - public Task DisplayClassAllocation_DoNotReportForNonCapturingLambdaAsync() - => VerifyCS.VerifyAnalyzerAsync(""" - using System; - using Roslyn.Utilities; + [Fact] + public Task DisplayClassAllocation_DoNotReportForNonCapturingLambdaAsync() + => VerifyCS.VerifyAnalyzerAsync(""" + using System; + using Roslyn.Utilities; - public class MyClass + public class MyClass + { + [PerformanceSensitive("uri")] + public void Sorter(int[] arr) { - [PerformanceSensitive("uri")] - public void Sorter(int[] arr) - { - System.Array.Sort(arr, (x, y) => x - y); - } + System.Array.Sort(arr, (x, y) => x - y); } - """); + } + """); - [Fact] - public Task DisplayClassAllocation_ReportForCapturingAnonymousMethodAsync() - => VerifyCS.VerifyAnalyzerAsync(""" - using System; - using Roslyn.Utilities; + [Fact] + public Task DisplayClassAllocation_ReportForCapturingAnonymousMethodAsync() + => VerifyCS.VerifyAnalyzerAsync(""" + using System; + using Roslyn.Utilities; - public class MyClass + public class MyClass + { + [PerformanceSensitive("uri")] + public void Sorter(int[] arr) { - [PerformanceSensitive("uri")] - public void Sorter(int[] arr) - { - int z = 2; - System.Array.Sort(arr, delegate(int x, int y) { return x - z; }); - } + int z = 2; + System.Array.Sort(arr, delegate(int x, int y) { return x - z; }); } - """, - // Test0.cs(9,13): warning HAA0302: The compiler will emit a class that will hold this as a field to allow capturing of this closure + } + """, + // Test0.cs(9,13): warning HAA0302: The compiler will emit a class that will hold this as a field to allow capturing of this closure #pragma warning disable RS0030 // Do not use banned APIs - VerifyCS.Diagnostic(DisplayClassAllocationAnalyzer.ClosureCaptureRule).WithLocation(9, 13), + VerifyCS.Diagnostic(DisplayClassAllocationAnalyzer.ClosureCaptureRule).WithLocation(9, 13), #pragma warning restore RS0030 // Do not use banned APIs - // Test0.cs(10,32): warning HAA0301: Heap allocation of closure Captures: z + // Test0.cs(10,32): warning HAA0301: Heap allocation of closure Captures: z #pragma warning disable RS0030 // Do not use banned APIs - VerifyCS.Diagnostic(DisplayClassAllocationAnalyzer.ClosureDriverRule).WithLocation(10, 32).WithArguments("z")); - } + VerifyCS.Diagnostic(DisplayClassAllocationAnalyzer.ClosureDriverRule).WithLocation(10, 32).WithArguments("z")); } diff --git a/src/roslyn/src/RoslynAnalyzers/PerformanceSensitiveAnalyzers/UnitTests/EnumeratorAllocationAnalyzerTests.cs b/src/roslyn/src/RoslynAnalyzers/PerformanceSensitiveAnalyzers/UnitTests/EnumeratorAllocationAnalyzerTests.cs index c79909c8862..eb8a5092ffa 100644 --- a/src/roslyn/src/RoslynAnalyzers/PerformanceSensitiveAnalyzers/UnitTests/EnumeratorAllocationAnalyzerTests.cs +++ b/src/roslyn/src/RoslynAnalyzers/PerformanceSensitiveAnalyzers/UnitTests/EnumeratorAllocationAnalyzerTests.cs @@ -3,152 +3,155 @@ // See the LICENSE file in the project root for more information. using System.Threading.Tasks; +using Microsoft.CodeAnalysis.CSharp.PerformanceSensitiveAnalyzers; +using Microsoft.CodeAnalysis.PerformanceSensitiveAnalyzers.UnitTests; +using Microsoft.CodeAnalysis.Testing; using Xunit; -using VerifyCS = Microsoft.CodeAnalysis.PerformanceSensitiveAnalyzers.UnitTests.CSharpPerformanceCodeFixVerifier< - Microsoft.CodeAnalysis.CSharp.PerformanceSensitiveAnalyzers.EnumeratorAllocationAnalyzer, - Microsoft.CodeAnalysis.Testing.EmptyCodeFixProvider>; -namespace Microsoft.CodeAnalysis.PerformanceSensitive.Analyzers.UnitTests +namespace Microsoft.CodeAnalysis.PerformanceSensitive.Analyzers.UnitTests; + +using VerifyCS = CSharpPerformanceCodeFixVerifier< + EnumeratorAllocationAnalyzer, + EmptyCodeFixProvider>; + +public sealed class EnumeratorAllocationAnalyzerTests { - public class EnumeratorAllocationAnalyzerTests - { - [Fact] - public Task EnumeratorAllocation_BasicAsync() - => VerifyCS.VerifyAnalyzerAsync(""" - using System.Collections.Generic; - using System; - using System.Linq; - using Roslyn.Utilities; - - public class MyClass + [Fact] + public Task EnumeratorAllocation_BasicAsync() + => VerifyCS.VerifyAnalyzerAsync(""" + using System.Collections.Generic; + using System; + using System.Linq; + using Roslyn.Utilities; + + public class MyClass + { + [PerformanceSensitive("uri")] + public void SomeMethod() { - [PerformanceSensitive("uri")] - public void SomeMethod() + int[] intData = new[] { 123, 32, 4 }; + IList iListData = new[] { 123, 32, 4 }; + List listData = new[] { 123, 32, 4 }.ToList(); + + foreach (var i in intData) { - int[] intData = new[] { 123, 32, 4 }; - IList iListData = new[] { 123, 32, 4 }; - List listData = new[] { 123, 32, 4 }.ToList(); - - foreach (var i in intData) - { - Console.WriteLine(i); - } - - foreach (var i in listData) - { - Console.WriteLine(i); - } - - foreach (var i in iListData) // Allocations (line 19) - { - Console.WriteLine(i); - } - - foreach (var i in (IEnumerable)intData) // Allocations (line 24) - { - Console.WriteLine(i); - } + Console.WriteLine(i); + } + + foreach (var i in listData) + { + Console.WriteLine(i); } - } - """, - // Test0.cs(25,24): warning HAA0401: Non-ValueType enumerator may result in a heap allocation -#pragma warning disable RS0030 // Do not use banned APIs - VerifyCS.Diagnostic().WithLocation(25, 24), -#pragma warning restore RS0030 // Do not use banned APIs - // Test0.cs(30,24): warning HAA0401: Non-ValueType enumerator may result in a heap allocation -#pragma warning disable RS0030 // Do not use banned APIs - VerifyCS.Diagnostic().WithLocation(30, 24)); - [Fact] - public Task EnumeratorAllocation_AdvancedAsync() - => VerifyCS.VerifyAnalyzerAsync(""" - using System.Collections.Generic; - using System; - using Roslyn.Utilities; + foreach (var i in iListData) // Allocations (line 19) + { + Console.WriteLine(i); + } - public class MyClass - { - [PerformanceSensitive("uri")] - public void SomeMethod() + foreach (var i in (IEnumerable)intData) // Allocations (line 24) { - // These next 3 are from the YouTube video - foreach (object a in new[] { 1, 2, 3}) // Allocations 'new [] { 1. 2, 3}' - { - Console.WriteLine(a.ToString()); - } - - IEnumerable fx1 = default(IEnumerable); - foreach (var f in fx1) // Allocations 'in' - { - } - - List fx2 = default(List); - foreach (var f in fx2) // NO Allocations - { - } + Console.WriteLine(i); } } - """, - // Test0.cs(17,24): warning HAA0401: Non-ValueType enumerator may result in a heap allocation + } + """, + // Test0.cs(25,24): warning HAA0401: Non-ValueType enumerator may result in a heap allocation #pragma warning disable RS0030 // Do not use banned APIs - VerifyCS.Diagnostic().WithLocation(17, 24)); - - [Fact] - public Task EnumeratorAllocation_Via_InvocationExpressionSyntaxAsync() - => VerifyCS.VerifyAnalyzerAsync(""" - using System.Collections.Generic; - using System.Collections; - using System; - using Roslyn.Utilities; - - public class MyClass + VerifyCS.Diagnostic().WithLocation(25, 24), +#pragma warning restore RS0030 // Do not use banned APIs + // Test0.cs(30,24): warning HAA0401: Non-ValueType enumerator may result in a heap allocation +#pragma warning disable RS0030 // Do not use banned APIs + VerifyCS.Diagnostic().WithLocation(30, 24)); + + [Fact] + public Task EnumeratorAllocation_AdvancedAsync() + => VerifyCS.VerifyAnalyzerAsync(""" + using System.Collections.Generic; + using System; + using Roslyn.Utilities; + + public class MyClass + { + [PerformanceSensitive("uri")] + public void SomeMethod() { - [PerformanceSensitive("uri")] - public void SomeMethod() + // These next 3 are from the YouTube video + foreach (object a in new[] { 1, 2, 3}) // Allocations 'new [] { 1. 2, 3}' { - var enumeratorRaw = GetIEnumerableRaw(); - while (enumeratorRaw.MoveNext()) - { - Console.WriteLine(enumeratorRaw.Current.ToString()); - } - - var enumeratorRawViaIEnumerable = GetIEnumeratorViaIEnumerable(); - while (enumeratorRawViaIEnumerable.MoveNext()) - { - Console.WriteLine(enumeratorRawViaIEnumerable.Current.ToString()); - } + Console.WriteLine(a.ToString()); } - private IEnumerator GetIEnumerableRaw() + IEnumerable fx1 = default(IEnumerable); + foreach (var f in fx1) // Allocations 'in' { - return new[] { 123, 32, 4 }.GetEnumerator(); } - private IEnumerator GetIEnumeratorViaIEnumerable() + List fx2 = default(List); + foreach (var f in fx2) // NO Allocations { - int[] intData = new[] { 123, 32, 4 }; - return (IEnumerator)intData.GetEnumerator(); } } - """, - // Test0.cs(17,43): warning HAA0401: Non-ValueType enumerator may result in a heap allocation + } + """, + // Test0.cs(17,24): warning HAA0401: Non-ValueType enumerator may result in a heap allocation #pragma warning disable RS0030 // Do not use banned APIs - VerifyCS.Diagnostic().WithLocation(17, 43)); - - [Fact] - public Task EnumeratorAllocation_IterateOverString_NoWarningAsync() - => VerifyCS.VerifyAnalyzerAsync(""" - using System; - using Roslyn.Utilities; - - public class MyClass + VerifyCS.Diagnostic().WithLocation(17, 24)); + + [Fact] + public Task EnumeratorAllocation_Via_InvocationExpressionSyntaxAsync() + => VerifyCS.VerifyAnalyzerAsync(""" + using System.Collections.Generic; + using System.Collections; + using System; + using Roslyn.Utilities; + + public class MyClass + { + [PerformanceSensitive("uri")] + public void SomeMethod() { - [PerformanceSensitive("uri")] - public void SomeMethod() + var enumeratorRaw = GetIEnumerableRaw(); + while (enumeratorRaw.MoveNext()) + { + Console.WriteLine(enumeratorRaw.Current.ToString()); + } + + var enumeratorRawViaIEnumerable = GetIEnumeratorViaIEnumerable(); + while (enumeratorRawViaIEnumerable.MoveNext()) { - foreach (char c in "aaa") { }; + Console.WriteLine(enumeratorRawViaIEnumerable.Current.ToString()); } } - """); - } + + private IEnumerator GetIEnumerableRaw() + { + return new[] { 123, 32, 4 }.GetEnumerator(); + } + + private IEnumerator GetIEnumeratorViaIEnumerable() + { + int[] intData = new[] { 123, 32, 4 }; + return (IEnumerator)intData.GetEnumerator(); + } + } + """, + // Test0.cs(17,43): warning HAA0401: Non-ValueType enumerator may result in a heap allocation +#pragma warning disable RS0030 // Do not use banned APIs + VerifyCS.Diagnostic().WithLocation(17, 43)); + + [Fact] + public Task EnumeratorAllocation_IterateOverString_NoWarningAsync() + => VerifyCS.VerifyAnalyzerAsync(""" + using System; + using Roslyn.Utilities; + + public class MyClass + { + [PerformanceSensitive("uri")] + public void SomeMethod() + { + foreach (char c in "aaa") { }; + } + } + """); } diff --git a/src/roslyn/src/RoslynAnalyzers/PerformanceSensitiveAnalyzers/UnitTests/ExplicitAllocationAnalyzerTests.cs b/src/roslyn/src/RoslynAnalyzers/PerformanceSensitiveAnalyzers/UnitTests/ExplicitAllocationAnalyzerTests.cs index 18798598180..208e5874c6f 100644 --- a/src/roslyn/src/RoslynAnalyzers/PerformanceSensitiveAnalyzers/UnitTests/ExplicitAllocationAnalyzerTests.cs +++ b/src/roslyn/src/RoslynAnalyzers/PerformanceSensitiveAnalyzers/UnitTests/ExplicitAllocationAnalyzerTests.cs @@ -4,755 +4,757 @@ using System.Threading.Tasks; using Microsoft.CodeAnalysis.PerformanceSensitiveAnalyzers; +using Microsoft.CodeAnalysis.PerformanceSensitiveAnalyzers.UnitTests; +using Microsoft.CodeAnalysis.Testing; using Test.Utilities; using Xunit; -using VerifyCS = Microsoft.CodeAnalysis.PerformanceSensitiveAnalyzers.UnitTests.CSharpPerformanceCodeFixVerifier< - Microsoft.CodeAnalysis.PerformanceSensitiveAnalyzers.ExplicitAllocationAnalyzer, - Microsoft.CodeAnalysis.Testing.EmptyCodeFixProvider>; -using VerifyVB = Microsoft.CodeAnalysis.PerformanceSensitiveAnalyzers.UnitTests.VisualBasicPerformanceCodeFixVerifier< - Microsoft.CodeAnalysis.PerformanceSensitiveAnalyzers.ExplicitAllocationAnalyzer, - Microsoft.CodeAnalysis.Testing.EmptyCodeFixProvider>; - -namespace Microsoft.CodeAnalysis.PerformanceSensitive.Analyzers.UnitTests -{ - public class ExplicitAllocationAnalyzerTests - { - [Fact] - public Task ExplicitAllocation_ObjectInitializerAsync() - => VerifyCS.VerifyAnalyzerAsync(""" - using System; - using Roslyn.Utilities; - - public class MyClass - { - [PerformanceSensitive("uri")] - public void Testing() - { - var @class = new TestClass { Name = "Bob" }; - } - } - public class TestClass - { - public string Name { get; set; } - } - """, -#pragma warning disable RS0030 // Do not use banned APIs - VerifyCS.Diagnostic(ExplicitAllocationAnalyzer.ObjectCreationRule).WithLocation(9, 22)); - - [Fact] - public Task ExplicitAllocation_ObjectInitializer_VisualBasicAsync() - => VerifyVB.VerifyAnalyzerAsync( - """ - Imports System - Imports Roslyn.Utilities - - Public Class A - - Public Sub Testing() - Dim instance = New TestClass With {.Name = "Bob"} - End Sub - End Class - - Public Class TestClass - Public Property Name As String - End Class - """, -#pragma warning disable RS0030 // Do not use banned APIs - VerifyVB.Diagnostic(ExplicitAllocationAnalyzer.ObjectCreationRule).WithLocation(7, 24)); +namespace Microsoft.CodeAnalysis.PerformanceSensitive.Analyzers.UnitTests; - [Fact] - public Task ExplicitAllocation_ObjectInitializerStruct_NoWarningAsync() - => VerifyCS.VerifyAnalyzerAsync(""" - using System; - using Roslyn.Utilities; +using VerifyCS = CSharpPerformanceCodeFixVerifier< + ExplicitAllocationAnalyzer, + EmptyCodeFixProvider>; +using VerifyVB = VisualBasicPerformanceCodeFixVerifier< + ExplicitAllocationAnalyzer, + EmptyCodeFixProvider>; - public class MyClass +public sealed class ExplicitAllocationAnalyzerTests +{ + [Fact] + public Task ExplicitAllocation_ObjectInitializerAsync() + => VerifyCS.VerifyAnalyzerAsync(""" + using System; + using Roslyn.Utilities; + + public class MyClass + { + [PerformanceSensitive("uri")] + public void Testing() { - [PerformanceSensitive("uri")] - public void Testing() - { - var @struct = new TestStruct { Name = "Bob" }; - } + var @class = new TestClass { Name = "Bob" }; } + } - public struct TestStruct + public class TestClass + { + public string Name { get; set; } + } + """, +#pragma warning disable RS0030 // Do not use banned APIs + VerifyCS.Diagnostic(ExplicitAllocationAnalyzer.ObjectCreationRule).WithLocation(9, 22)); + + [Fact] + public Task ExplicitAllocation_ObjectInitializer_VisualBasicAsync() + => VerifyVB.VerifyAnalyzerAsync( + """ + Imports System + Imports Roslyn.Utilities + + Public Class A + + Public Sub Testing() + Dim instance = New TestClass With {.Name = "Bob"} + End Sub + End Class + + Public Class TestClass + Public Property Name As String + End Class + """, +#pragma warning disable RS0030 // Do not use banned APIs + VerifyVB.Diagnostic(ExplicitAllocationAnalyzer.ObjectCreationRule).WithLocation(7, 24)); + + [Fact] + public Task ExplicitAllocation_ObjectInitializerStruct_NoWarningAsync() + => VerifyCS.VerifyAnalyzerAsync(""" + using System; + using Roslyn.Utilities; + + public class MyClass + { + [PerformanceSensitive("uri")] + public void Testing() { - public string Name { get; set; } + var @struct = new TestStruct { Name = "Bob" }; } - """); - - [Fact] - public Task ExplicitAllocation_ObjectInitializerStruct_NoWarning_VisualBasicAsync() - => VerifyVB.VerifyAnalyzerAsync(""" - Imports System - Imports Roslyn.Utilities - - Public Class A - - Public Sub Testing() - Dim instance = New TestClass With {.Name = "Bob"} - End Sub - End Class - - Public Structure TestClass - Public Property Name As String - End Structure - """); - - [Fact] - public Task ExplicitAllocation_ImplicitArrayCreationAsync() - => VerifyCS.VerifyAnalyzerAsync(""" - using System.Collections.Generic; - using Roslyn.Utilities; - - public class MyClass + } + + public struct TestStruct + { + public string Name { get; set; } + } + """); + + [Fact] + public Task ExplicitAllocation_ObjectInitializerStruct_NoWarning_VisualBasicAsync() + => VerifyVB.VerifyAnalyzerAsync(""" + Imports System + Imports Roslyn.Utilities + + Public Class A + + Public Sub Testing() + Dim instance = New TestClass With {.Name = "Bob"} + End Sub + End Class + + Public Structure TestClass + Public Property Name As String + End Structure + """); + + [Fact] + public Task ExplicitAllocation_ImplicitArrayCreationAsync() + => VerifyCS.VerifyAnalyzerAsync(""" + using System.Collections.Generic; + using Roslyn.Utilities; + + public class MyClass + { + [PerformanceSensitive("uri")] + public void Testing() { - [PerformanceSensitive("uri")] - public void Testing() - { - int[] intData = new[] { 123, 32, 4 }; - } + int[] intData = new[] { 123, 32, 4 }; } - """, + } + """, #pragma warning disable RS0030 // Do not use banned APIs - VerifyCS.Diagnostic(ExplicitAllocationAnalyzer.ArrayCreationRule).WithLocation(9, 25)); - - [Fact] - public Task ExplicitAllocation_ImplicitArrayCreation_VisualBasicAsync() - => VerifyVB.VerifyAnalyzerAsync(""" - Imports System.Collections.Generic - Imports Roslyn.Utilities - - Public Class A - - Public Sub Testing() - Dim intData() As Integer = {123, 32, 4} - End Sub - End Class - """, + VerifyCS.Diagnostic(ExplicitAllocationAnalyzer.ArrayCreationRule).WithLocation(9, 25)); + + [Fact] + public Task ExplicitAllocation_ImplicitArrayCreation_VisualBasicAsync() + => VerifyVB.VerifyAnalyzerAsync(""" + Imports System.Collections.Generic + Imports Roslyn.Utilities + + Public Class A + + Public Sub Testing() + Dim intData() As Integer = {123, 32, 4} + End Sub + End Class + """, #pragma warning disable RS0030 // Do not use banned APIs - VerifyVB.Diagnostic(ExplicitAllocationAnalyzer.ArrayCreationRule).WithLocation(7, 36)); - - [Fact] - public Task ExplicitAllocation_AnonymousObjectCreationAsync() - => VerifyCS.VerifyAnalyzerAsync(""" - using System; - using Roslyn.Utilities; - - public class MyClass + VerifyVB.Diagnostic(ExplicitAllocationAnalyzer.ArrayCreationRule).WithLocation(7, 36)); + + [Fact] + public Task ExplicitAllocation_AnonymousObjectCreationAsync() + => VerifyCS.VerifyAnalyzerAsync(""" + using System; + using Roslyn.Utilities; + + public class MyClass + { + [PerformanceSensitive("uri")] + public void Testing() { - [PerformanceSensitive("uri")] - public void Testing() - { - var temp = new { A = 123, Name = "Test", }; - } + var temp = new { A = 123, Name = "Test", }; } - """, + } + """, #pragma warning disable RS0030 // Do not use banned APIs - VerifyCS.Diagnostic(ExplicitAllocationAnalyzer.AnonymousObjectCreationRule).WithLocation(9, 20)); - - [Fact] - public Task ExplicitAllocation_AnonymousObjectCreation_VisualBasicAsync() - => VerifyVB.VerifyAnalyzerAsync(""" - Imports System - Imports Roslyn.Utilities - - Public Class A - - Public Sub Testing() - Dim temp = New With {Key .B = 123, .Name = "Test"} - End Sub - End Class - """, + VerifyCS.Diagnostic(ExplicitAllocationAnalyzer.AnonymousObjectCreationRule).WithLocation(9, 20)); + + [Fact] + public Task ExplicitAllocation_AnonymousObjectCreation_VisualBasicAsync() + => VerifyVB.VerifyAnalyzerAsync(""" + Imports System + Imports Roslyn.Utilities + + Public Class A + + Public Sub Testing() + Dim temp = New With {Key .B = 123, .Name = "Test"} + End Sub + End Class + """, #pragma warning disable RS0030 // Do not use banned APIs - VerifyVB.Diagnostic(ExplicitAllocationAnalyzer.AnonymousObjectCreationRule).WithLocation(7, 20)); - - [Fact] - public Task ExplicitAllocation_ArrayCreationAsync() - => VerifyCS.VerifyAnalyzerAsync(""" - using System.Collections.Generic; - using Roslyn.Utilities; - - public class MyClass + VerifyVB.Diagnostic(ExplicitAllocationAnalyzer.AnonymousObjectCreationRule).WithLocation(7, 20)); + + [Fact] + public Task ExplicitAllocation_ArrayCreationAsync() + => VerifyCS.VerifyAnalyzerAsync(""" + using System.Collections.Generic; + using Roslyn.Utilities; + + public class MyClass + { + [PerformanceSensitive("uri")] + public void Testing() { - [PerformanceSensitive("uri")] - public void Testing() - { - int[] intData = new int[] { 123, 32, 4 }; - } + int[] intData = new int[] { 123, 32, 4 }; } - """, + } + """, #pragma warning disable RS0030 // Do not use banned APIs - VerifyCS.Diagnostic(ExplicitAllocationAnalyzer.ArrayCreationRule).WithLocation(9, 25)); - - [Fact] - public Task ExplicitAllocation_ArrayCreation_VisualBasicAsync() - => VerifyVB.VerifyAnalyzerAsync(""" - Imports System.Collections.Generic - Imports Roslyn.Utilities - - Public Class A - - Public Sub Testing() - Dim intData = New Integer() {123, 32, 4} - End Sub - End Class - """, + VerifyCS.Diagnostic(ExplicitAllocationAnalyzer.ArrayCreationRule).WithLocation(9, 25)); + + [Fact] + public Task ExplicitAllocation_ArrayCreation_VisualBasicAsync() + => VerifyVB.VerifyAnalyzerAsync(""" + Imports System.Collections.Generic + Imports Roslyn.Utilities + + Public Class A + + Public Sub Testing() + Dim intData = New Integer() {123, 32, 4} + End Sub + End Class + """, #pragma warning disable RS0030 // Do not use banned APIs - VerifyVB.Diagnostic(ExplicitAllocationAnalyzer.ArrayCreationRule).WithLocation(7, 23)); - - [Fact] - public Task ExplicitAllocation_ObjectCreationAsync() - => VerifyCS.VerifyAnalyzerAsync(""" - using System; - using Roslyn.Utilities; - - public class MyClass + VerifyVB.Diagnostic(ExplicitAllocationAnalyzer.ArrayCreationRule).WithLocation(7, 23)); + + [Fact] + public Task ExplicitAllocation_ObjectCreationAsync() + => VerifyCS.VerifyAnalyzerAsync(""" + using System; + using Roslyn.Utilities; + + public class MyClass + { + [PerformanceSensitive("uri")] + public void Testing() { - [PerformanceSensitive("uri")] - public void Testing() - { - var allocation = new String('a', 10); - } + var allocation = new String('a', 10); } - """, + } + """, #pragma warning disable RS0030 // Do not use banned APIs - VerifyCS.Diagnostic(ExplicitAllocationAnalyzer.ObjectCreationRule).WithLocation(9, 26)); - - [Fact] - public Task ExplicitAllocation_ObjectCreation_VisualBasicAsync() - => VerifyVB.VerifyAnalyzerAsync(""" - Imports System - Imports Roslyn.Utilities - - Public Class A - - Public Sub Testing() - Dim allocation = New String("a"c, 10) - End Sub - End Class - """, + VerifyCS.Diagnostic(ExplicitAllocationAnalyzer.ObjectCreationRule).WithLocation(9, 26)); + + [Fact] + public Task ExplicitAllocation_ObjectCreation_VisualBasicAsync() + => VerifyVB.VerifyAnalyzerAsync(""" + Imports System + Imports Roslyn.Utilities + + Public Class A + + Public Sub Testing() + Dim allocation = New String("a"c, 10) + End Sub + End Class + """, #pragma warning disable RS0030 // Do not use banned APIs - VerifyVB.Diagnostic(ExplicitAllocationAnalyzer.ObjectCreationRule).WithLocation(7, 26)); - - [Fact] - public Task ExplicitAllocation_LetClauseAsync() - => VerifyCS.VerifyAnalyzerAsync(""" - using System.Collections.Generic; - using System.Linq; - using Roslyn.Utilities; - - public class MyClass + VerifyVB.Diagnostic(ExplicitAllocationAnalyzer.ObjectCreationRule).WithLocation(7, 26)); + + [Fact] + public Task ExplicitAllocation_LetClauseAsync() + => VerifyCS.VerifyAnalyzerAsync(""" + using System.Collections.Generic; + using System.Linq; + using Roslyn.Utilities; + + public class MyClass + { + [PerformanceSensitive("uri")] + public void Testing() { - [PerformanceSensitive("uri")] - public void Testing() - { - int[] intData = new[] { 123, 32, 4 }; - var result = (from a in intData - let b = a * 3 - select b).ToList(); - } + int[] intData = new[] { 123, 32, 4 }; + var result = (from a in intData + let b = a * 3 + select b).ToList(); } - """, + } + """, #pragma warning disable RS0030 // Do not use banned APIs - VerifyCS.Diagnostic(ExplicitAllocationAnalyzer.ArrayCreationRule).WithLocation(10, 25), + VerifyCS.Diagnostic(ExplicitAllocationAnalyzer.ArrayCreationRule).WithLocation(10, 25), #pragma warning restore RS0030 // Do not use banned APIs #pragma warning disable RS0030 // Do not use banned APIs - VerifyCS.Diagnostic(ExplicitAllocationAnalyzer.LetCauseRule).WithLocation(12, 23)); - - [Fact] - public Task ExplicitAllocation_LetClause_VisualBasicAsync() - => VerifyVB.VerifyAnalyzerAsync(""" - Imports System.Collections.Generic - Imports System.Linq - Imports Roslyn.Utilities - - Public Class A - - Public Sub Testing() - Dim intData() As Integer = {123, 32, 4} - Dim result = (From x In intData - Let b = x * 3 - Select b).ToList() - End Sub - End Class - """, + VerifyCS.Diagnostic(ExplicitAllocationAnalyzer.LetCauseRule).WithLocation(12, 23)); + + [Fact] + public Task ExplicitAllocation_LetClause_VisualBasicAsync() + => VerifyVB.VerifyAnalyzerAsync(""" + Imports System.Collections.Generic + Imports System.Linq + Imports Roslyn.Utilities + + Public Class A + + Public Sub Testing() + Dim intData() As Integer = {123, 32, 4} + Dim result = (From x In intData + Let b = x * 3 + Select b).ToList() + End Sub + End Class + """, #pragma warning disable RS0030 // Do not use banned APIs - VerifyVB.Diagnostic(ExplicitAllocationAnalyzer.ArrayCreationRule).WithLocation(8, 36), + VerifyVB.Diagnostic(ExplicitAllocationAnalyzer.ArrayCreationRule).WithLocation(8, 36), #pragma warning restore RS0030 // Do not use banned APIs #pragma warning disable RS0030 // Do not use banned APIs - VerifyVB.Diagnostic(ExplicitAllocationAnalyzer.LetCauseRule).WithLocation(10, 27)); + VerifyVB.Diagnostic(ExplicitAllocationAnalyzer.LetCauseRule).WithLocation(10, 27)); - [Fact] - [WorkItem(7995606, "http://stackoverflow.com/questions/7995606/boxing-occurrence-in-c-sharp")] - public Task Converting_any_value_type_to_System_Object_typeAsync() - => VerifyCS.VerifyAnalyzerAsync(""" - using Roslyn.Utilities; + [Fact] + [WorkItem(7995606, "http://stackoverflow.com/questions/7995606/boxing-occurrence-in-c-sharp")] + public Task Converting_any_value_type_to_System_Object_typeAsync() + => VerifyCS.VerifyAnalyzerAsync(""" + using Roslyn.Utilities; - public struct S { } + public struct S { } - public class MyClass + public class MyClass + { + [PerformanceSensitive("uri")] + public void SomeMethod() { - [PerformanceSensitive("uri")] - public void SomeMethod() - { - object box = new S(); - } + object box = new S(); } - """, + } + """, #pragma warning disable RS0030 // Do not use banned APIs - VerifyCS.Diagnostic(ExplicitAllocationAnalyzer.ObjectCreationRule).WithLocation(10, 22)); - - [Fact] - [WorkItem(7995606, "http://stackoverflow.com/questions/7995606/boxing-occurrence-in-c-sharp")] - public Task Converting_any_value_type_to_System_Object_type_VisualBasicAsync() - => VerifyVB.VerifyAnalyzerAsync(""" - Imports Roslyn.Utilities - - Public Structure S - End Structure - - Public Class A - - Public Sub SomeMethod() - Dim box As Object = new S() - End Sub - End Class - """, + VerifyCS.Diagnostic(ExplicitAllocationAnalyzer.ObjectCreationRule).WithLocation(10, 22)); + + [Fact] + [WorkItem(7995606, "http://stackoverflow.com/questions/7995606/boxing-occurrence-in-c-sharp")] + public Task Converting_any_value_type_to_System_Object_type_VisualBasicAsync() + => VerifyVB.VerifyAnalyzerAsync(""" + Imports Roslyn.Utilities + + Public Structure S + End Structure + + Public Class A + + Public Sub SomeMethod() + Dim box As Object = new S() + End Sub + End Class + """, #pragma warning disable RS0030 // Do not use banned APIs - VerifyVB.Diagnostic(ExplicitAllocationAnalyzer.ObjectCreationRule).WithLocation(9, 29)); + VerifyVB.Diagnostic(ExplicitAllocationAnalyzer.ObjectCreationRule).WithLocation(9, 29)); - [Fact] - [WorkItem(7995606, "http://stackoverflow.com/questions/7995606/boxing-occurrence-in-c-sharp")] - public Task Converting_any_value_type_to_System_ValueType_typeAsync() - => VerifyCS.VerifyAnalyzerAsync(""" - using Roslyn.Utilities; + [Fact] + [WorkItem(7995606, "http://stackoverflow.com/questions/7995606/boxing-occurrence-in-c-sharp")] + public Task Converting_any_value_type_to_System_ValueType_typeAsync() + => VerifyCS.VerifyAnalyzerAsync(""" + using Roslyn.Utilities; - public struct S { } + public struct S { } - public class MyClass + public class MyClass + { + [PerformanceSensitive("uri")] + public void SomeMethod() { - [PerformanceSensitive("uri")] - public void SomeMethod() - { - System.ValueType box = new S(); - } + System.ValueType box = new S(); } - """, + } + """, #pragma warning disable RS0030 // Do not use banned APIs - VerifyCS.Diagnostic(ExplicitAllocationAnalyzer.ObjectCreationRule).WithLocation(10, 32)); - - [Fact] - [WorkItem(7995606, "http://stackoverflow.com/questions/7995606/boxing-occurrence-in-c-sharp")] - public Task Converting_any_value_type_to_System_ValueType_type_VisualBasicAsync() - => VerifyVB.VerifyAnalyzerAsync(""" - Imports Roslyn.Utilities - - Public Structure S - End Structure - - Public Class A - - Public Sub SomeMethod() - Dim box As System.ValueType = new S() - End Sub - End Class - """, + VerifyCS.Diagnostic(ExplicitAllocationAnalyzer.ObjectCreationRule).WithLocation(10, 32)); + + [Fact] + [WorkItem(7995606, "http://stackoverflow.com/questions/7995606/boxing-occurrence-in-c-sharp")] + public Task Converting_any_value_type_to_System_ValueType_type_VisualBasicAsync() + => VerifyVB.VerifyAnalyzerAsync(""" + Imports Roslyn.Utilities + + Public Structure S + End Structure + + Public Class A + + Public Sub SomeMethod() + Dim box As System.ValueType = new S() + End Sub + End Class + """, #pragma warning disable RS0030 // Do not use banned APIs - VerifyVB.Diagnostic(ExplicitAllocationAnalyzer.ObjectCreationRule).WithLocation(9, 39)); + VerifyVB.Diagnostic(ExplicitAllocationAnalyzer.ObjectCreationRule).WithLocation(9, 39)); - [Fact] - [WorkItem(7995606, "http://stackoverflow.com/questions/7995606/boxing-occurrence-in-c-sharp")] - public Task Converting_any_value_type_into_interface_referenceAsync() - => VerifyCS.VerifyAnalyzerAsync(""" - using Roslyn.Utilities; + [Fact] + [WorkItem(7995606, "http://stackoverflow.com/questions/7995606/boxing-occurrence-in-c-sharp")] + public Task Converting_any_value_type_into_interface_referenceAsync() + => VerifyCS.VerifyAnalyzerAsync(""" + using Roslyn.Utilities; - interface I { } + interface I { } - public struct S : I { } + public struct S : I { } - public class MyClass + public class MyClass + { + [PerformanceSensitive("uri")] + public void SomeMethod() { - [PerformanceSensitive("uri")] - public void SomeMethod() - { - I box = new S(); - } + I box = new S(); } - """, + } + """, #pragma warning disable RS0030 // Do not use banned APIs - VerifyCS.Diagnostic(ExplicitAllocationAnalyzer.ObjectCreationRule).WithLocation(12, 17)); - - [Fact] - [WorkItem(7995606, "http://stackoverflow.com/questions/7995606/boxing-occurrence-in-c-sharp")] - public Task Converting_any_value_type_into_interface_reference_VisualBasicAsync() - => VerifyVB.VerifyAnalyzerAsync(""" - Imports Roslyn.Utilities - - Interface I - End Interface - - Public Structure S - Implements I - End Structure - - Public Class A - - Public Sub SomeMethod() - Dim box As I = new S() - End Sub - End Class - """, + VerifyCS.Diagnostic(ExplicitAllocationAnalyzer.ObjectCreationRule).WithLocation(12, 17)); + + [Fact] + [WorkItem(7995606, "http://stackoverflow.com/questions/7995606/boxing-occurrence-in-c-sharp")] + public Task Converting_any_value_type_into_interface_reference_VisualBasicAsync() + => VerifyVB.VerifyAnalyzerAsync(""" + Imports Roslyn.Utilities + + Interface I + End Interface + + Public Structure S + Implements I + End Structure + + Public Class A + + Public Sub SomeMethod() + Dim box As I = new S() + End Sub + End Class + """, #pragma warning disable RS0030 // Do not use banned APIs - VerifyVB.Diagnostic(ExplicitAllocationAnalyzer.ObjectCreationRule).WithLocation(13, 24)); + VerifyVB.Diagnostic(ExplicitAllocationAnalyzer.ObjectCreationRule).WithLocation(13, 24)); - [Fact] - public Task ExplicitAllocation_StructCreation_NoWarningAsync() - => VerifyCS.VerifyAnalyzerAsync(""" - using System; - using Roslyn.Utilities; + [Fact] + public Task ExplicitAllocation_StructCreation_NoWarningAsync() + => VerifyCS.VerifyAnalyzerAsync(""" + using System; + using Roslyn.Utilities; - public struct S { } + public struct S { } - public class MyClass - { + public class MyClass + { - [PerformanceSensitive("uri")] - public void Testing() - { - var noBox1 = new DateTime(); - S noBox2 = new S(); - } - } - """); - - [Fact] - public Task ExplicitAllocation_StructCreation_NoWarning_VisualBasicAsync() - => VerifyVB.VerifyAnalyzerAsync(""" - Imports System - Imports Roslyn.Utilities - - Public Structure S - End Structure - - Public Class A - - Public Sub Testing() - Dim noBox1 = new DateTime() - Dim noBox2 As S = new S() - End Sub - End Class - """); - - [Fact] - public Task ExplicitAllocation_PrimitiveTypeConversion_NoWarningAsync() - => VerifyCS.VerifyAnalyzerAsync(""" - using System; - using Roslyn.Utilities; - - public class MyClass + [PerformanceSensitive("uri")] + public void Testing() { - [PerformanceSensitive("uri")] - public void Testing() - { - double x = new int(); - } + var noBox1 = new DateTime(); + S noBox2 = new S(); } - """); - - [Fact] - public Task ExplicitAllocation_PrimitiveTypeConversion_NoWarning_VisualBasicAsync() - => VerifyVB.VerifyAnalyzerAsync(""" - Imports System - Imports Roslyn.Utilities - - Public Class A - - Public Sub Testing() - Dim x As Double = New Integer() - End Sub - End Class - """); - - [Fact] - public Task ExplicitAllocation_ImplicitValueTypeConversion_NoWarningAsync() - => VerifyCS.VerifyAnalyzerAsync(""" - using System; - using Roslyn.Utilities; - - struct A + } + """); + + [Fact] + public Task ExplicitAllocation_StructCreation_NoWarning_VisualBasicAsync() + => VerifyVB.VerifyAnalyzerAsync(""" + Imports System + Imports Roslyn.Utilities + + Public Structure S + End Structure + + Public Class A + + Public Sub Testing() + Dim noBox1 = new DateTime() + Dim noBox2 As S = new S() + End Sub + End Class + """); + + [Fact] + public Task ExplicitAllocation_PrimitiveTypeConversion_NoWarningAsync() + => VerifyCS.VerifyAnalyzerAsync(""" + using System; + using Roslyn.Utilities; + + public class MyClass + { + [PerformanceSensitive("uri")] + public void Testing() { - public static implicit operator A(B other) - { - return new A(); - } + double x = new int(); } - - struct B + } + """); + + [Fact] + public Task ExplicitAllocation_PrimitiveTypeConversion_NoWarning_VisualBasicAsync() + => VerifyVB.VerifyAnalyzerAsync(""" + Imports System + Imports Roslyn.Utilities + + Public Class A + + Public Sub Testing() + Dim x As Double = New Integer() + End Sub + End Class + """); + + [Fact] + public Task ExplicitAllocation_ImplicitValueTypeConversion_NoWarningAsync() + => VerifyCS.VerifyAnalyzerAsync(""" + using System; + using Roslyn.Utilities; + + struct A + { + public static implicit operator A(B other) { + return new A(); } + } - public class MyClass + struct B + { + } + + public class MyClass + { + [PerformanceSensitive("uri")] + public void Testing() { - [PerformanceSensitive("uri")] - public void Testing() - { - A a = new B(); - } + A a = new B(); } - """); - - [Fact] - public Task ExplicitAllocation_ImplicitValueTypeConversion_NoWarning_VisualBasicAsync() - => VerifyVB.VerifyAnalyzerAsync(""" - Imports System - Imports Roslyn.Utilities - - Structure A - Public Shared Widening Operator CType(other As B) As A - Return New A() - End Operator - End Structure - - Structure B - End Structure - - Public Class C - - Public Sub Testing() - Dim a As A = New B() - End Sub - End Class - """); - - [Fact] - public Task ExplicitAllocation_NoParamsArrayCreationAsync() - => VerifyCS.VerifyAnalyzerAsync(""" - using System.Collections.Generic; - using Roslyn.Utilities; - - public class MyClass + } + """); + + [Fact] + public Task ExplicitAllocation_ImplicitValueTypeConversion_NoWarning_VisualBasicAsync() + => VerifyVB.VerifyAnalyzerAsync(""" + Imports System + Imports Roslyn.Utilities + + Structure A + Public Shared Widening Operator CType(other As B) As A + Return New A() + End Operator + End Structure + + Structure B + End Structure + + Public Class C + + Public Sub Testing() + Dim a As A = New B() + End Sub + End Class + """); + + [Fact] + public Task ExplicitAllocation_NoParamsArrayCreationAsync() + => VerifyCS.VerifyAnalyzerAsync(""" + using System.Collections.Generic; + using Roslyn.Utilities; + + public class MyClass + { + [PerformanceSensitive("uri")] + public void Testing(params int[] values) { - [PerformanceSensitive("uri")] - public void Testing(params int[] values) - { - Testing(); - } + Testing(); } - """); - - [Fact] - public Task ExplicitAllocation_NoParamsArrayCreation_VisualBasicAsync() - => VerifyVB.VerifyAnalyzerAsync(""" - Imports System.Collections.Generic - Imports Roslyn.Utilities - - Public Class A - - Public Sub Testing(ParamArray values() As Integer) - Testing() - End Sub - End Class - """); - - [Fact] - public Task ExplicitAllocation_ExplicitDelegateCreationAsync() - => VerifyCS.VerifyAnalyzerAsync(""" - using System; - using Roslyn.Utilities; - - public class MyClass + } + """); + + [Fact] + public Task ExplicitAllocation_NoParamsArrayCreation_VisualBasicAsync() + => VerifyVB.VerifyAnalyzerAsync(""" + Imports System.Collections.Generic + Imports Roslyn.Utilities + + Public Class A + + Public Sub Testing(ParamArray values() As Integer) + Testing() + End Sub + End Class + """); + + [Fact] + public Task ExplicitAllocation_ExplicitDelegateCreationAsync() + => VerifyCS.VerifyAnalyzerAsync(""" + using System; + using Roslyn.Utilities; + + public class MyClass + { + [PerformanceSensitive("uri")] + public void Testing(object sender, EventArgs e) { - [PerformanceSensitive("uri")] - public void Testing(object sender, EventArgs e) - { - var handler = new EventHandler(Testing); - } + var handler = new EventHandler(Testing); } - """, + } + """, #pragma warning disable RS0030 // Do not use banned APIs - VerifyCS.Diagnostic(ExplicitAllocationAnalyzer.ObjectCreationRule).WithLocation(9, 23)); - - [Fact] - public Task ExplicitAllocation_ExplicitDelegateCreation_VisualBasicAsync() - => VerifyVB.VerifyAnalyzerAsync(""" - Imports System - Imports Roslyn.Utilities - - Public Class A - - Public Sub Testing(sender As Object, e As EventArgs) - Dim handler = new EventHandler(AddressOf Testing) - End Sub - End Class - """, + VerifyCS.Diagnostic(ExplicitAllocationAnalyzer.ObjectCreationRule).WithLocation(9, 23)); + + [Fact] + public Task ExplicitAllocation_ExplicitDelegateCreation_VisualBasicAsync() + => VerifyVB.VerifyAnalyzerAsync(""" + Imports System + Imports Roslyn.Utilities + + Public Class A + + Public Sub Testing(sender As Object, e As EventArgs) + Dim handler = new EventHandler(AddressOf Testing) + End Sub + End Class + """, #pragma warning disable RS0030 // Do not use banned APIs - VerifyVB.Diagnostic(ExplicitAllocationAnalyzer.ObjectCreationRule).WithLocation(7, 23)); - - [Fact] - public Task ExplicitAllocation_ImplicitDelegateCreationAsync() - => VerifyCS.VerifyAnalyzerAsync(""" - using System; - using Roslyn.Utilities; - - public class MyClass + VerifyVB.Diagnostic(ExplicitAllocationAnalyzer.ObjectCreationRule).WithLocation(7, 23)); + + [Fact] + public Task ExplicitAllocation_ImplicitDelegateCreationAsync() + => VerifyCS.VerifyAnalyzerAsync(""" + using System; + using Roslyn.Utilities; + + public class MyClass + { + [PerformanceSensitive("uri")] + public void Testing(object sender, EventArgs e) { - [PerformanceSensitive("uri")] - public void Testing(object sender, EventArgs e) - { - EventHandler handler = Testing; - } + EventHandler handler = Testing; } - """); - - [Fact] - public Task ExplicitAllocation_ImplicitDelegateCreation_VisualBasicAsync() - => VerifyVB.VerifyAnalyzerAsync(""" - Imports System - Imports Roslyn.Utilities - - Public Class A - - Public Sub Testing(sender As Object, e As EventArgs) - Dim handler As EventHandler = AddressOf Testing - End Sub - End Class - """); - - [Fact] - public Task ExplicitAllocation_ListInitializerCreationAsync() - => VerifyCS.VerifyAnalyzerAsync(""" - using System.Collections.Generic; - using Roslyn.Utilities; - - public class MyClass + } + """); + + [Fact] + public Task ExplicitAllocation_ImplicitDelegateCreation_VisualBasicAsync() + => VerifyVB.VerifyAnalyzerAsync(""" + Imports System + Imports Roslyn.Utilities + + Public Class A + + Public Sub Testing(sender As Object, e As EventArgs) + Dim handler As EventHandler = AddressOf Testing + End Sub + End Class + """); + + [Fact] + public Task ExplicitAllocation_ListInitializerCreationAsync() + => VerifyCS.VerifyAnalyzerAsync(""" + using System.Collections.Generic; + using Roslyn.Utilities; + + public class MyClass + { + [PerformanceSensitive("uri")] + public void Testing() { - [PerformanceSensitive("uri")] - public void Testing() - { - var intData = new List { 3, 4 }; - } + var intData = new List { 3, 4 }; } - """, + } + """, #pragma warning disable RS0030 // Do not use banned APIs - VerifyCS.Diagnostic(ExplicitAllocationAnalyzer.ObjectCreationRule).WithLocation(9, 23)); - - [Fact] - public Task ExplicitAllocation_ListInitializerCreation_VisualBasicAsync() - => VerifyVB.VerifyAnalyzerAsync(""" - Imports System.Collections.Generic - Imports Roslyn.Utilities - - Public Class A - - Public Sub Testing() - Dim intData = New List(Of Integer) From {3, 4} - End Sub - End Class - """, + VerifyCS.Diagnostic(ExplicitAllocationAnalyzer.ObjectCreationRule).WithLocation(9, 23)); + + [Fact] + public Task ExplicitAllocation_ListInitializerCreation_VisualBasicAsync() + => VerifyVB.VerifyAnalyzerAsync(""" + Imports System.Collections.Generic + Imports Roslyn.Utilities + + Public Class A + + Public Sub Testing() + Dim intData = New List(Of Integer) From {3, 4} + End Sub + End Class + """, #pragma warning disable RS0030 // Do not use banned APIs - VerifyVB.Diagnostic(ExplicitAllocationAnalyzer.ObjectCreationRule).WithLocation(7, 23)); - - [Fact] - public Task ExplicitAllocation_GenericObjectCreationAsync() - => VerifyCS.VerifyAnalyzerAsync(""" - using System; - using Roslyn.Utilities; - - public class MyClass + VerifyVB.Diagnostic(ExplicitAllocationAnalyzer.ObjectCreationRule).WithLocation(7, 23)); + + [Fact] + public Task ExplicitAllocation_GenericObjectCreationAsync() + => VerifyCS.VerifyAnalyzerAsync(""" + using System; + using Roslyn.Utilities; + + public class MyClass + { + [PerformanceSensitive("uri")] + public void Testing() + where T : class, new() { - [PerformanceSensitive("uri")] - public void Testing() - where T : class, new() - { - var allocation = new T(); - } + var allocation = new T(); } - """, + } + """, #pragma warning disable RS0030 // Do not use banned APIs - VerifyCS.Diagnostic(ExplicitAllocationAnalyzer.ObjectCreationRule).WithLocation(10, 26)); - - [Fact] - public Task ExplicitAllocation_GenericObjectCreation_VisualBasicAsync() - => VerifyVB.VerifyAnalyzerAsync(""" - Imports System - Imports Roslyn.Utilities - - Public Class A - - Public Sub Testing(Of T As {Class, New})() - Dim allocation = New T() - End Sub - End Class - """, + VerifyCS.Diagnostic(ExplicitAllocationAnalyzer.ObjectCreationRule).WithLocation(10, 26)); + + [Fact] + public Task ExplicitAllocation_GenericObjectCreation_VisualBasicAsync() + => VerifyVB.VerifyAnalyzerAsync(""" + Imports System + Imports Roslyn.Utilities + + Public Class A + + Public Sub Testing(Of T As {Class, New})() + Dim allocation = New T() + End Sub + End Class + """, #pragma warning disable RS0030 // Do not use banned APIs - VerifyVB.Diagnostic(ExplicitAllocationAnalyzer.ObjectCreationRule).WithLocation(7, 26)); - - [Fact] - public Task ExplicitAllocation_GenericObjectCreation2Async() - => VerifyCS.VerifyAnalyzerAsync(""" - using System; - using Roslyn.Utilities; - - public class MyClass + VerifyVB.Diagnostic(ExplicitAllocationAnalyzer.ObjectCreationRule).WithLocation(7, 26)); + + [Fact] + public Task ExplicitAllocation_GenericObjectCreation2Async() + => VerifyCS.VerifyAnalyzerAsync(""" + using System; + using Roslyn.Utilities; + + public class MyClass + { + [PerformanceSensitive("uri")] + public void Testing() + where T : struct { - [PerformanceSensitive("uri")] - public void Testing() - where T : struct - { - object allocation = new T(); - } + object allocation = new T(); } - """, + } + """, #pragma warning disable RS0030 // Do not use banned APIs - VerifyCS.Diagnostic(ExplicitAllocationAnalyzer.ObjectCreationRule).WithLocation(10, 29)); - - [Fact] - public Task ExplicitAllocation_GenericObjectCreation2_VisualBasicAsync() - => VerifyVB.VerifyAnalyzerAsync(""" - Imports System - Imports Roslyn.Utilities - - Public Class A - - Public Sub Testing(Of T As Structure)() - Dim allocation As Object = New T() - End Sub - End Class - """, + VerifyCS.Diagnostic(ExplicitAllocationAnalyzer.ObjectCreationRule).WithLocation(10, 29)); + + [Fact] + public Task ExplicitAllocation_GenericObjectCreation2_VisualBasicAsync() + => VerifyVB.VerifyAnalyzerAsync(""" + Imports System + Imports Roslyn.Utilities + + Public Class A + + Public Sub Testing(Of T As Structure)() + Dim allocation As Object = New T() + End Sub + End Class + """, #pragma warning disable RS0030 // Do not use banned APIs - VerifyVB.Diagnostic(ExplicitAllocationAnalyzer.ObjectCreationRule).WithLocation(7, 36)); - - [Fact] - public Task ExplicitAllocation_GenericObjectCreation3Async() - => VerifyCS.VerifyAnalyzerAsync(""" - using System; - using Roslyn.Utilities; - - public class MyClass + VerifyVB.Diagnostic(ExplicitAllocationAnalyzer.ObjectCreationRule).WithLocation(7, 36)); + + [Fact] + public Task ExplicitAllocation_GenericObjectCreation3Async() + => VerifyCS.VerifyAnalyzerAsync(""" + using System; + using Roslyn.Utilities; + + public class MyClass + { + [PerformanceSensitive("uri")] + public void Testing() + where T : struct { - [PerformanceSensitive("uri")] - public void Testing() - where T : struct - { - T value = new T(); - } + T value = new T(); } - """); - - [Fact] - public Task ExplicitAllocation_GenericObjectCreation3_VisualBasicAsync() - => VerifyVB.VerifyAnalyzerAsync(""" - Imports System - Imports Roslyn.Utilities - - Public Class A - - Public Sub Testing(Of T As Structure)() - Dim value As T = new T() - End Sub - End Class - """); - } + } + """); + + [Fact] + public Task ExplicitAllocation_GenericObjectCreation3_VisualBasicAsync() + => VerifyVB.VerifyAnalyzerAsync(""" + Imports System + Imports Roslyn.Utilities + + Public Class A + + Public Sub Testing(Of T As Structure)() + Dim value As T = new T() + End Sub + End Class + """); } diff --git a/src/roslyn/src/RoslynAnalyzers/PerformanceSensitiveAnalyzers/UnitTests/TypeConversionAllocationAnalyzerTests.cs b/src/roslyn/src/RoslynAnalyzers/PerformanceSensitiveAnalyzers/UnitTests/TypeConversionAllocationAnalyzerTests.cs index 331dceb9828..39c7bd51887 100644 --- a/src/roslyn/src/RoslynAnalyzers/PerformanceSensitiveAnalyzers/UnitTests/TypeConversionAllocationAnalyzerTests.cs +++ b/src/roslyn/src/RoslynAnalyzers/PerformanceSensitiveAnalyzers/UnitTests/TypeConversionAllocationAnalyzerTests.cs @@ -4,810 +4,812 @@ using System.Threading.Tasks; using Microsoft.CodeAnalysis.CSharp.PerformanceSensitiveAnalyzers; +using Microsoft.CodeAnalysis.PerformanceSensitiveAnalyzers.UnitTests; +using Microsoft.CodeAnalysis.Testing; using Test.Utilities; using Xunit; -using VerifyCS = Microsoft.CodeAnalysis.PerformanceSensitiveAnalyzers.UnitTests.CSharpPerformanceCodeFixVerifier< - Microsoft.CodeAnalysis.CSharp.PerformanceSensitiveAnalyzers.TypeConversionAllocationAnalyzer, - Microsoft.CodeAnalysis.Testing.EmptyCodeFixProvider>; -namespace Microsoft.CodeAnalysis.PerformanceSensitive.Analyzers.UnitTests +namespace Microsoft.CodeAnalysis.PerformanceSensitive.Analyzers.UnitTests; + +using VerifyCS = CSharpPerformanceCodeFixVerifier< + TypeConversionAllocationAnalyzer, + EmptyCodeFixProvider>; + +public sealed class TypeConversionAllocationAnalyzerTests { - public class TypeConversionAllocationAnalyzerTests - { - [Fact] - public Task TypeConversionAllocation_ArgumentSyntaxAsync() - => VerifyCS.VerifyAnalyzerAsync(""" - using System; - using Roslyn.Utilities; + [Fact] + public Task TypeConversionAllocation_ArgumentSyntaxAsync() + => VerifyCS.VerifyAnalyzerAsync(""" + using System; + using Roslyn.Utilities; - public class MyObject + public class MyObject + { + public MyObject(object obj) { - public MyObject(object obj) - { - } + } - private void ObjCall(object obj) - { - } + private void ObjCall(object obj) + { + } - [PerformanceSensitive("uri")] - public void SomeMethod() - { - ObjCall(10); // Allocation - _ = new MyObject(10); // Allocation - } + [PerformanceSensitive("uri")] + public void SomeMethod() + { + ObjCall(10); // Allocation + _ = new MyObject(10); // Allocation } - """, + } + """, #pragma warning disable RS0030 // Do not use banned APIs - VerifyCS.Diagnostic(TypeConversionAllocationAnalyzer.ValueTypeToReferenceTypeConversionRule).WithLocation(17, 17), + VerifyCS.Diagnostic(TypeConversionAllocationAnalyzer.ValueTypeToReferenceTypeConversionRule).WithLocation(17, 17), #pragma warning restore RS0030 // Do not use banned APIs #pragma warning disable RS0030 // Do not use banned APIs - VerifyCS.Diagnostic(TypeConversionAllocationAnalyzer.ValueTypeToReferenceTypeConversionRule).WithLocation(18, 26) + VerifyCS.Diagnostic(TypeConversionAllocationAnalyzer.ValueTypeToReferenceTypeConversionRule).WithLocation(18, 26) #pragma warning restore RS0030 // Do not use banned APIs - ); + ); - [Fact] - public Task TypeConversionAllocation_ArgumentSyntax_WithDelegatesAsync() - => VerifyCS.VerifyAnalyzerAsync(""" - using System; - using Roslyn.Utilities; + [Fact] + public Task TypeConversionAllocation_ArgumentSyntax_WithDelegatesAsync() + => VerifyCS.VerifyAnalyzerAsync(""" + using System; + using Roslyn.Utilities; - public class MyClass + public class MyClass + { + [PerformanceSensitive("uri")] + public void Testing() { - [PerformanceSensitive("uri")] - public void Testing() - { - var @class = new MyClass(); - @class.ProcessFunc(someObjCall); // implicit, so Allocation - @class.ProcessFunc(new Func(someObjCall)); // Explicit, so NO Allocation - } + var @class = new MyClass(); + @class.ProcessFunc(someObjCall); // implicit, so Allocation + @class.ProcessFunc(new Func(someObjCall)); // Explicit, so NO Allocation + } - public void ProcessFunc(Func func) - { - } + public void ProcessFunc(Func func) + { + } - private string someObjCall(object obj) => null; + private string someObjCall(object obj) => null; + } + + public struct MyStruct + { + [PerformanceSensitive("uri")] + public void Testing() + { + var @struct = new MyStruct(); + @struct.ProcessFunc(someObjCall); // implicit allocation + boxing + @struct.ProcessFunc(new Func(someObjCall)); // Explicit allocation + boxing } - public struct MyStruct + public void ProcessFunc(Func func) { - [PerformanceSensitive("uri")] - public void Testing() - { - var @struct = new MyStruct(); - @struct.ProcessFunc(someObjCall); // implicit allocation + boxing - @struct.ProcessFunc(new Func(someObjCall)); // Explicit allocation + boxing - } + } - public void ProcessFunc(Func func) - { - } + private string someObjCall(object obj) => null; + } + """, + // Test0.cs(10,28): warning HAA0603: This will allocate a delegate instance + VerifyCS.Diagnostic(TypeConversionAllocationAnalyzer.MethodGroupAllocationRule).WithSpan(10, 28, 10, 39), + // Test0.cs(27,29): warning HAA0602: Struct instance method being used for delegate creation, this will result in a boxing instruction + VerifyCS.Diagnostic(TypeConversionAllocationAnalyzer.MethodGroupAllocationRule).WithSpan(27, 29, 27, 40), + // Test0.cs(27,29): warning HAA0603: This will allocate a delegate instance + VerifyCS.Diagnostic(TypeConversionAllocationAnalyzer.DelegateOnStructInstanceRule).WithSpan(27, 29, 27, 40), + // Test0.cs(28,54): warning HAA0602: Struct instance method being used for delegate creation, this will result in a boxing instruction + VerifyCS.Diagnostic(TypeConversionAllocationAnalyzer.DelegateOnStructInstanceRule).WithSpan(28, 54, 28, 65)); - private string someObjCall(object obj) => null; - } - """, - // Test0.cs(10,28): warning HAA0603: This will allocate a delegate instance - VerifyCS.Diagnostic(TypeConversionAllocationAnalyzer.MethodGroupAllocationRule).WithSpan(10, 28, 10, 39), - // Test0.cs(27,29): warning HAA0602: Struct instance method being used for delegate creation, this will result in a boxing instruction - VerifyCS.Diagnostic(TypeConversionAllocationAnalyzer.MethodGroupAllocationRule).WithSpan(27, 29, 27, 40), - // Test0.cs(27,29): warning HAA0603: This will allocate a delegate instance - VerifyCS.Diagnostic(TypeConversionAllocationAnalyzer.DelegateOnStructInstanceRule).WithSpan(27, 29, 27, 40), - // Test0.cs(28,54): warning HAA0602: Struct instance method being used for delegate creation, this will result in a boxing instruction - VerifyCS.Diagnostic(TypeConversionAllocationAnalyzer.DelegateOnStructInstanceRule).WithSpan(28, 54, 28, 65)); - - [Fact] - public Task TypeConversionAllocation_ReturnStatementSyntaxAsync() - => VerifyCS.VerifyAnalyzerAsync(""" - using System; - using Roslyn.Utilities; - - public class MyObject - { - public Object Obj1 - { - [PerformanceSensitive("uri")] - get { return 0; } - } + [Fact] + public Task TypeConversionAllocation_ReturnStatementSyntaxAsync() + => VerifyCS.VerifyAnalyzerAsync(""" + using System; + using Roslyn.Utilities; + public class MyObject + { + public Object Obj1 + { [PerformanceSensitive("uri")] - public Object Obj2 - { - get { return 0; } - } + get { return 0; } + } + + [PerformanceSensitive("uri")] + public Object Obj2 + { + get { return 0; } } - """, - // Test0.cs(9,22): warning HAA0601: Value type to reference type conversion causes boxing at call site (here), and unboxing at the callee-site. Consider using generics if applicable + } + """, + // Test0.cs(9,22): warning HAA0601: Value type to reference type conversion causes boxing at call site (here), and unboxing at the callee-site. Consider using generics if applicable #pragma warning disable RS0030 // Do not use banned APIs - VerifyCS.Diagnostic(TypeConversionAllocationAnalyzer.ValueTypeToReferenceTypeConversionRule).WithLocation(9, 22), + VerifyCS.Diagnostic(TypeConversionAllocationAnalyzer.ValueTypeToReferenceTypeConversionRule).WithLocation(9, 22), #pragma warning restore RS0030 // Do not use banned APIs - // Test0.cs(15,22): warning HAA0601: Value type to reference type conversion causes boxing at call site (here), and unboxing at the callee-site. Consider using generics if applicable + // Test0.cs(15,22): warning HAA0601: Value type to reference type conversion causes boxing at call site (here), and unboxing at the callee-site. Consider using generics if applicable #pragma warning disable RS0030 // Do not use banned APIs - VerifyCS.Diagnostic(TypeConversionAllocationAnalyzer.ValueTypeToReferenceTypeConversionRule).WithLocation(15, 22)); + VerifyCS.Diagnostic(TypeConversionAllocationAnalyzer.ValueTypeToReferenceTypeConversionRule).WithLocation(15, 22)); - [Fact] - public Task TypeConversionAllocation_ReturnStatementSyntax_NoAllocAsync() - => VerifyCS.VerifyAnalyzerAsync(""" - using System; - using Roslyn.Utilities; + [Fact] + public Task TypeConversionAllocation_ReturnStatementSyntax_NoAllocAsync() + => VerifyCS.VerifyAnalyzerAsync(""" + using System; + using Roslyn.Utilities; - public class MyObject + public class MyObject + { + [PerformanceSensitive("uri")] + public Object ObjNoAllocation1 { get { return 0.ToString(); } } + + public Object ObjNoAllocation2 { [PerformanceSensitive("uri")] - public Object ObjNoAllocation1 { get { return 0.ToString(); } } - - public Object ObjNoAllocation2 - { - [PerformanceSensitive("uri")] - get { return 0.ToString(); } - } + get { return 0.ToString(); } } - """); + } + """); - [Fact] - public Task TypeConversionAllocation_YieldStatementSyntaxAsync() - => VerifyCS.VerifyAnalyzerAsync(""" - using System; - using System.Collections.Generic; - using Roslyn.Utilities; + [Fact] + public Task TypeConversionAllocation_YieldStatementSyntaxAsync() + => VerifyCS.VerifyAnalyzerAsync(""" + using System; + using System.Collections.Generic; + using Roslyn.Utilities; - public class MyClass + public class MyClass + { + public void SomeMethod() { - public void SomeMethod() + foreach (var item in GetItems()) { - foreach (var item in GetItems()) - { - } - - foreach (var item in GetItemsNoAllocation()) - { - } } - [PerformanceSensitive("uri")] - public IEnumerable GetItems() + foreach (var item in GetItemsNoAllocation()) { - yield return 0; // Allocation - yield break; } + } - [PerformanceSensitive("uri")] - public IEnumerable GetItemsNoAllocation() - { - yield return 0; // NO Allocation (IEnumerable) - yield break; - } + [PerformanceSensitive("uri")] + public IEnumerable GetItems() + { + yield return 0; // Allocation + yield break; + } + + [PerformanceSensitive("uri")] + public IEnumerable GetItemsNoAllocation() + { + yield return 0; // NO Allocation (IEnumerable) + yield break; } - """, - // Test0.cs(21,22): warning HAA0601: Value type to reference type conversion causes boxing at call site (here), and unboxing at the callee-site. Consider using generics if applicable + } + """, + // Test0.cs(21,22): warning HAA0601: Value type to reference type conversion causes boxing at call site (here), and unboxing at the callee-site. Consider using generics if applicable #pragma warning disable RS0030 // Do not use banned APIs - VerifyCS.Diagnostic(TypeConversionAllocationAnalyzer.ValueTypeToReferenceTypeConversionRule).WithLocation(21, 22)); + VerifyCS.Diagnostic(TypeConversionAllocationAnalyzer.ValueTypeToReferenceTypeConversionRule).WithLocation(21, 22)); - [Fact] - public Task TypeConversionAllocation_BinaryExpressionSyntaxAsync() - => VerifyCS.VerifyAnalyzerAsync(""" - using System; - using Roslyn.Utilities; + [Fact] + public Task TypeConversionAllocation_BinaryExpressionSyntaxAsync() + => VerifyCS.VerifyAnalyzerAsync(""" + using System; + using Roslyn.Utilities; - public class MyClass + public class MyClass + { + [PerformanceSensitive("uri")] + public void SomeMethod() { - [PerformanceSensitive("uri")] - public void SomeMethod() - { - object x = "blah"; - object a1 = x ?? 0; // Allocation - object a2 = x ?? 0.ToString(); // No Allocation + object x = "blah"; + object a1 = x ?? 0; // Allocation + object a2 = x ?? 0.ToString(); // No Allocation - var b1 = 10 as object; // Allocation - var b2 = 10.ToString() as object; // No Allocation - } + var b1 = 10 as object; // Allocation + var b2 = 10.ToString() as object; // No Allocation } - """, - // Test0.cs(10,26): warning HAA0601: Value type to reference type conversion causes boxing at call site (here), and unboxing at the callee-site. Consider using generics if applicable + } + """, + // Test0.cs(10,26): warning HAA0601: Value type to reference type conversion causes boxing at call site (here), and unboxing at the callee-site. Consider using generics if applicable #pragma warning disable RS0030 // Do not use banned APIs - VerifyCS.Diagnostic(TypeConversionAllocationAnalyzer.ValueTypeToReferenceTypeConversionRule).WithLocation(10, 26), + VerifyCS.Diagnostic(TypeConversionAllocationAnalyzer.ValueTypeToReferenceTypeConversionRule).WithLocation(10, 26), #pragma warning restore RS0030 // Do not use banned APIs - // Test0.cs(13,18): warning HAA0601: Value type to reference type conversion causes boxing at call site (here), and unboxing at the callee-site. Consider using generics if applicable + // Test0.cs(13,18): warning HAA0601: Value type to reference type conversion causes boxing at call site (here), and unboxing at the callee-site. Consider using generics if applicable #pragma warning disable RS0030 // Do not use banned APIs - VerifyCS.Diagnostic(TypeConversionAllocationAnalyzer.ValueTypeToReferenceTypeConversionRule).WithLocation(13, 18)); + VerifyCS.Diagnostic(TypeConversionAllocationAnalyzer.ValueTypeToReferenceTypeConversionRule).WithLocation(13, 18)); - [Fact] - public Task TypeConversionAllocation_BinaryExpressionSyntax_WithDelegatesAsync() - => VerifyCS.VerifyAnalyzerAsync(""" - using System; - using Roslyn.Utilities; + [Fact] + public Task TypeConversionAllocation_BinaryExpressionSyntax_WithDelegatesAsync() + => VerifyCS.VerifyAnalyzerAsync(""" + using System; + using Roslyn.Utilities; - public class MyClass + public class MyClass + { + [PerformanceSensitive("uri")] + public void Testing() { - [PerformanceSensitive("uri")] - public void Testing() - { - Func temp = null; - var result1 = temp ?? someObjCall; // implicit, so Allocation - var result2 = temp ?? new Func(someObjCall); // Explicit, so NO Allocation - } + Func temp = null; + var result1 = temp ?? someObjCall; // implicit, so Allocation + var result2 = temp ?? new Func(someObjCall); // Explicit, so NO Allocation + } - private string someObjCall(object obj) - { - return obj.ToString(); - } + private string someObjCall(object obj) + { + return obj.ToString(); } + } - public struct MyStruct + public struct MyStruct + { + [PerformanceSensitive("uri")] + public void Testing() { - [PerformanceSensitive("uri")] - public void Testing() - { - Func temp = null; - var result1 = temp ?? someObjCall; // implicit allocation + boxing - var result2 = temp ?? new Func(someObjCall); // Explicit allocation + boxing - } + Func temp = null; + var result1 = temp ?? someObjCall; // implicit allocation + boxing + var result2 = temp ?? new Func(someObjCall); // Explicit allocation + boxing + } - private string someObjCall(object obj) - { - return obj.ToString(); - } + private string someObjCall(object obj) + { + return obj.ToString(); } - """, - // Test0.cs(10,31): warning HAA0603: This will allocate a delegate instance - VerifyCS.Diagnostic(TypeConversionAllocationAnalyzer.MethodGroupAllocationRule).WithSpan(10, 31, 10, 42), - // Test0.cs(26,31): warning HAA0602: Struct instance method being used for delegate creation, this will result in a boxing instruction - VerifyCS.Diagnostic(TypeConversionAllocationAnalyzer.DelegateOnStructInstanceRule).WithSpan(26, 31, 26, 42), - // Test0.cs(26,31): warning HAA0603: This will allocate a delegate instance - VerifyCS.Diagnostic(TypeConversionAllocationAnalyzer.MethodGroupAllocationRule).WithSpan(26, 31, 26, 42), - // Test0.cs(27,56): warning HAA0602: Struct instance method being used for delegate creation, this will result in a boxing instruction - VerifyCS.Diagnostic(TypeConversionAllocationAnalyzer.DelegateOnStructInstanceRule).WithSpan(27, 56, 27, 67)); + } + """, + // Test0.cs(10,31): warning HAA0603: This will allocate a delegate instance + VerifyCS.Diagnostic(TypeConversionAllocationAnalyzer.MethodGroupAllocationRule).WithSpan(10, 31, 10, 42), + // Test0.cs(26,31): warning HAA0602: Struct instance method being used for delegate creation, this will result in a boxing instruction + VerifyCS.Diagnostic(TypeConversionAllocationAnalyzer.DelegateOnStructInstanceRule).WithSpan(26, 31, 26, 42), + // Test0.cs(26,31): warning HAA0603: This will allocate a delegate instance + VerifyCS.Diagnostic(TypeConversionAllocationAnalyzer.MethodGroupAllocationRule).WithSpan(26, 31, 26, 42), + // Test0.cs(27,56): warning HAA0602: Struct instance method being used for delegate creation, this will result in a boxing instruction + VerifyCS.Diagnostic(TypeConversionAllocationAnalyzer.DelegateOnStructInstanceRule).WithSpan(27, 56, 27, 67)); - [Fact] - public Task TypeConversionAllocation_EqualsValueClauseSyntaxAsync() - => VerifyCS.VerifyAnalyzerAsync(""" - using System; - using Roslyn.Utilities; + [Fact] + public Task TypeConversionAllocation_EqualsValueClauseSyntaxAsync() + => VerifyCS.VerifyAnalyzerAsync(""" + using System; + using Roslyn.Utilities; - public class MyClass + public class MyClass + { + [PerformanceSensitive("uri")] + public void SomeMethod() { - [PerformanceSensitive("uri")] - public void SomeMethod() + for (object i = 0;;) // Allocation { - for (object i = 0;;) // Allocation - { - } + } - for (int i = 0;;) // NO Allocation - { - } + for (int i = 0;;) // NO Allocation + { } } - """, - // Test0.cs(9,25): warning HAA0601: Value type to reference type conversion causes boxing at call site (here), and unboxing at the callee-site. Consider using generics if applicable + } + """, + // Test0.cs(9,25): warning HAA0601: Value type to reference type conversion causes boxing at call site (here), and unboxing at the callee-site. Consider using generics if applicable #pragma warning disable RS0030 // Do not use banned APIs - VerifyCS.Diagnostic(TypeConversionAllocationAnalyzer.ValueTypeToReferenceTypeConversionRule).WithLocation(9, 25)); + VerifyCS.Diagnostic(TypeConversionAllocationAnalyzer.ValueTypeToReferenceTypeConversionRule).WithLocation(9, 25)); - [Fact] - public Task TypeConversionAllocation_EqualsValueClauseSyntax_WithDelegatesAsync() - => VerifyCS.VerifyAnalyzerAsync(""" - using System; - using Roslyn.Utilities; + [Fact] + public Task TypeConversionAllocation_EqualsValueClauseSyntax_WithDelegatesAsync() + => VerifyCS.VerifyAnalyzerAsync(""" + using System; + using Roslyn.Utilities; - public class MyClass + public class MyClass + { + [PerformanceSensitive("uri")] + public void Testing() { - [PerformanceSensitive("uri")] - public void Testing() - { - Func func2 = someObjCall; // implicit, so Allocation - Func func1 = new Func(someObjCall); // Explicit, so NO Allocation - } + Func func2 = someObjCall; // implicit, so Allocation + Func func1 = new Func(someObjCall); // Explicit, so NO Allocation + } - private string someObjCall(object obj) - { - return obj.ToString(); - } + private string someObjCall(object obj) + { + return obj.ToString(); } + } - public struct MyStruct + public struct MyStruct + { + [PerformanceSensitive("uri")] + public void Testing() { - [PerformanceSensitive("uri")] - public void Testing() - { - Func func2 = someObjCall; // implicit allocation + boxing - Func func1 = new Func(someObjCall); // Explicit allocation + boxing - } + Func func2 = someObjCall; // implicit allocation + boxing + Func func1 = new Func(someObjCall); // Explicit allocation + boxing + } - private string someObjCall(object obj) - { - return obj.ToString(); - } + private string someObjCall(object obj) + { + return obj.ToString(); } - """, - // Test0.cs(9,38): warning HAA0603: This will allocate a delegate instance - VerifyCS.Diagnostic(TypeConversionAllocationAnalyzer.MethodGroupAllocationRule).WithSpan(9, 38, 9, 49), - // Test0.cs(24,38): warning HAA0602: Struct instance method being used for delegate creation, this will result in a boxing instruction - VerifyCS.Diagnostic(TypeConversionAllocationAnalyzer.DelegateOnStructInstanceRule).WithSpan(24, 38, 24, 49), - // Test0.cs(24,38): warning HAA0603: This will allocate a delegate instance - VerifyCS.Diagnostic(TypeConversionAllocationAnalyzer.MethodGroupAllocationRule).WithSpan(24, 38, 24, 49), - // Test0.cs(25,63): warning HAA0602: Struct instance method being used for delegate creation, this will result in a boxing instruction - VerifyCS.Diagnostic(TypeConversionAllocationAnalyzer.DelegateOnStructInstanceRule).WithSpan(25, 63, 25, 74)); - - [Fact] - [WorkItem(2, "https://github.com/mjsabby/RoslynClrHeapAllocationAnalyzer/issues/2")] - public Task TypeConversionAllocation_EqualsValueClause_ExplicitMethodGroupAllocation_BugAsync() - => VerifyCS.VerifyAnalyzerAsync(""" - using System; - using Roslyn.Utilities; - - public class MyClass + } + """, + // Test0.cs(9,38): warning HAA0603: This will allocate a delegate instance + VerifyCS.Diagnostic(TypeConversionAllocationAnalyzer.MethodGroupAllocationRule).WithSpan(9, 38, 9, 49), + // Test0.cs(24,38): warning HAA0602: Struct instance method being used for delegate creation, this will result in a boxing instruction + VerifyCS.Diagnostic(TypeConversionAllocationAnalyzer.DelegateOnStructInstanceRule).WithSpan(24, 38, 24, 49), + // Test0.cs(24,38): warning HAA0603: This will allocate a delegate instance + VerifyCS.Diagnostic(TypeConversionAllocationAnalyzer.MethodGroupAllocationRule).WithSpan(24, 38, 24, 49), + // Test0.cs(25,63): warning HAA0602: Struct instance method being used for delegate creation, this will result in a boxing instruction + VerifyCS.Diagnostic(TypeConversionAllocationAnalyzer.DelegateOnStructInstanceRule).WithSpan(25, 63, 25, 74)); + + [Fact] + [WorkItem(2, "https://github.com/mjsabby/RoslynClrHeapAllocationAnalyzer/issues/2")] + public Task TypeConversionAllocation_EqualsValueClause_ExplicitMethodGroupAllocation_BugAsync() + => VerifyCS.VerifyAnalyzerAsync(""" + using System; + using Roslyn.Utilities; + + public class MyClass + { + [PerformanceSensitive("uri")] + public void Testing() { - [PerformanceSensitive("uri")] - public void Testing() - { - Action methodGroup = this.Method; - } + Action methodGroup = this.Method; + } - private void Method() - { - } + private void Method() + { } + } - public struct MyStruct + public struct MyStruct + { + [PerformanceSensitive("uri")] + public void Testing() { - [PerformanceSensitive("uri")] - public void Testing() - { - Action methodGroup = this.Method; - } + Action methodGroup = this.Method; + } - private void Method() - { - } + private void Method() + { } - """, - // Test0.cs(9,30): warning HAA0603: This will allocate a delegate instance + } + """, + // Test0.cs(9,30): warning HAA0603: This will allocate a delegate instance #pragma warning disable RS0030 // Do not use banned APIs - VerifyCS.Diagnostic(TypeConversionAllocationAnalyzer.MethodGroupAllocationRule).WithLocation(9, 30), + VerifyCS.Diagnostic(TypeConversionAllocationAnalyzer.MethodGroupAllocationRule).WithLocation(9, 30), #pragma warning restore RS0030 // Do not use banned APIs - // Test0.cs(22,30): warning HAA0603: This will allocate a delegate instance + // Test0.cs(22,30): warning HAA0603: This will allocate a delegate instance #pragma warning disable RS0030 // Do not use banned APIs - VerifyCS.Diagnostic(TypeConversionAllocationAnalyzer.MethodGroupAllocationRule).WithLocation(22, 30), + VerifyCS.Diagnostic(TypeConversionAllocationAnalyzer.MethodGroupAllocationRule).WithLocation(22, 30), #pragma warning restore RS0030 // Do not use banned APIs - // Test0.cs(22,30): warning HAA0602: Struct instance method being used for delegate creation, this will result in a boxing instruction + // Test0.cs(22,30): warning HAA0602: Struct instance method being used for delegate creation, this will result in a boxing instruction #pragma warning disable RS0030 // Do not use banned APIs - VerifyCS.Diagnostic(TypeConversionAllocationAnalyzer.DelegateOnStructInstanceRule).WithLocation(22, 30)); - - [Fact] - public Task TypeConversionAllocation_ConditionalExpressionSyntaxAsync() - => VerifyCS.VerifyAnalyzerAsync(""" - using System; - using Roslyn.Utilities; - - public class MyClass - { - [PerformanceSensitive("uri")] - public void Testing() - { - object obj = "test"; - object test1 = true ? 0 : obj; // Allocation - object test2 = true ? 0.ToString() : obj; // NO Allocation - } - } - """, - // Test0.cs(10,31): warning HAA0601: Value type to reference type conversion causes boxing at call site (here), and unboxing at the callee-site. Consider using generics if applicable + VerifyCS.Diagnostic(TypeConversionAllocationAnalyzer.DelegateOnStructInstanceRule).WithLocation(22, 30)); + + [Fact] + public Task TypeConversionAllocation_ConditionalExpressionSyntaxAsync() + => VerifyCS.VerifyAnalyzerAsync(""" + using System; + using Roslyn.Utilities; + + public class MyClass + { + [PerformanceSensitive("uri")] + public void Testing() + { + object obj = "test"; + object test1 = true ? 0 : obj; // Allocation + object test2 = true ? 0.ToString() : obj; // NO Allocation + } + } + """, + // Test0.cs(10,31): warning HAA0601: Value type to reference type conversion causes boxing at call site (here), and unboxing at the callee-site. Consider using generics if applicable #pragma warning disable RS0030 // Do not use banned APIs - VerifyCS.Diagnostic(TypeConversionAllocationAnalyzer.ValueTypeToReferenceTypeConversionRule).WithLocation(10, 31)); + VerifyCS.Diagnostic(TypeConversionAllocationAnalyzer.ValueTypeToReferenceTypeConversionRule).WithLocation(10, 31)); - [Fact] - public Task TypeConversionAllocation_CastExpressionSyntaxAsync() - => VerifyCS.VerifyAnalyzerAsync(""" - using System; - using Roslyn.Utilities; + [Fact] + public Task TypeConversionAllocation_CastExpressionSyntaxAsync() + => VerifyCS.VerifyAnalyzerAsync(""" + using System; + using Roslyn.Utilities; - public class MyClass + public class MyClass + { + [PerformanceSensitive("uri")] + public void Testing() { - [PerformanceSensitive("uri")] - public void Testing() - { - var f1 = (object)5; // Allocation - var f2 = (object)"5"; // NO Allocation - } + var f1 = (object)5; // Allocation + var f2 = (object)"5"; // NO Allocation } - """, - // Test0.cs(9,26): warning HAA0601: Value type to reference type conversion causes boxing at call site (here), and unboxing at the callee-site. Consider using generics if applicable + } + """, + // Test0.cs(9,26): warning HAA0601: Value type to reference type conversion causes boxing at call site (here), and unboxing at the callee-site. Consider using generics if applicable #pragma warning disable RS0030 // Do not use banned APIs - VerifyCS.Diagnostic(TypeConversionAllocationAnalyzer.ValueTypeToReferenceTypeConversionRule).WithLocation(9, 26)); + VerifyCS.Diagnostic(TypeConversionAllocationAnalyzer.ValueTypeToReferenceTypeConversionRule).WithLocation(9, 26)); - [Fact] - public async Task TypeConversionAllocation_ArgumentWithImplicitStringCastOperatorAsync() - { - const string programWithoutImplicitCastOperator = """ - using System; - using Roslyn.Utilities; + [Fact] + public async Task TypeConversionAllocation_ArgumentWithImplicitStringCastOperatorAsync() + { + const string programWithoutImplicitCastOperator = """ + using System; + using Roslyn.Utilities; - public struct AStruct + public struct AStruct + { + [PerformanceSensitive("uri")] + public static void Dump(AStruct astruct) { - [PerformanceSensitive("uri")] - public static void Dump(AStruct astruct) - { - System.Console.WriteLine(astruct); - } + System.Console.WriteLine(astruct); } - """; + } + """; - await VerifyCS.VerifyAnalyzerAsync(programWithoutImplicitCastOperator, - // Test0.cs(10,34): warning HAA0601: Value type to reference type conversion causes boxing at call site (here), and unboxing at the callee-site. Consider using generics if applicable + await VerifyCS.VerifyAnalyzerAsync(programWithoutImplicitCastOperator, + // Test0.cs(10,34): warning HAA0601: Value type to reference type conversion causes boxing at call site (here), and unboxing at the callee-site. Consider using generics if applicable #pragma warning disable RS0030 // Do not use banned APIs - VerifyCS.Diagnostic(TypeConversionAllocationAnalyzer.ValueTypeToReferenceTypeConversionRule).WithLocation(9, 34)); + VerifyCS.Diagnostic(TypeConversionAllocationAnalyzer.ValueTypeToReferenceTypeConversionRule).WithLocation(9, 34)); #pragma warning restore RS0030 // Do not use banned APIs - const string programWithImplicitCastOperator = """ - using System; - using Roslyn.Utilities; + const string programWithImplicitCastOperator = """ + using System; + using Roslyn.Utilities; - public struct AStruct - { - public readonly string WrappedString; + public struct AStruct + { + public readonly string WrappedString; - public AStruct(string s) - { - WrappedString = s ?? ""; - } + public AStruct(string s) + { + WrappedString = s ?? ""; + } - [PerformanceSensitive("uri")] - public static void Dump(AStruct astruct) - { - System.Console.WriteLine(astruct); - } + [PerformanceSensitive("uri")] + public static void Dump(AStruct astruct) + { + System.Console.WriteLine(astruct); + } - [PerformanceSensitive("uri")] - public static implicit operator string(AStruct astruct) - { - return astruct.WrappedString; - } + [PerformanceSensitive("uri")] + public static implicit operator string(AStruct astruct) + { + return astruct.WrappedString; } - """; - await VerifyCS.VerifyAnalyzerAsync(programWithImplicitCastOperator); - } + } + """; + await VerifyCS.VerifyAnalyzerAsync(programWithImplicitCastOperator); + } - [Fact] - public async Task TypeConversionAllocation_YieldReturnImplicitStringCastOperatorAsync() - { - const string programWithoutImplicitCastOperator = """ - using System; - using Roslyn.Utilities; + [Fact] + public async Task TypeConversionAllocation_YieldReturnImplicitStringCastOperatorAsync() + { + const string programWithoutImplicitCastOperator = """ + using System; + using Roslyn.Utilities; - public struct AStruct + public struct AStruct + { + [PerformanceSensitive("uri")] + public System.Collections.Generic.IEnumerator GetEnumerator() { - [PerformanceSensitive("uri")] - public System.Collections.Generic.IEnumerator GetEnumerator() - { - yield return this; - } + yield return this; } - """; + } + """; - await VerifyCS.VerifyAnalyzerAsync(programWithoutImplicitCastOperator, - // Test0.cs(10,22): warning HAA0601: Value type to reference type conversion causes boxing at call site (here), and unboxing at the callee-site. Consider using generics if applicable + await VerifyCS.VerifyAnalyzerAsync(programWithoutImplicitCastOperator, + // Test0.cs(10,22): warning HAA0601: Value type to reference type conversion causes boxing at call site (here), and unboxing at the callee-site. Consider using generics if applicable #pragma warning disable RS0030 // Do not use banned APIs - VerifyCS.Diagnostic(TypeConversionAllocationAnalyzer.ValueTypeToReferenceTypeConversionRule).WithLocation(9, 22)); + VerifyCS.Diagnostic(TypeConversionAllocationAnalyzer.ValueTypeToReferenceTypeConversionRule).WithLocation(9, 22)); #pragma warning restore RS0030 // Do not use banned APIs - const string programWithImplicitCastOperator = """ - using System; - using Roslyn.Utilities; + const string programWithImplicitCastOperator = """ + using System; + using Roslyn.Utilities; - public struct AStruct + public struct AStruct + { + [PerformanceSensitive("uri")] + public System.Collections.Generic.IEnumerator GetEnumerator() { - [PerformanceSensitive("uri")] - public System.Collections.Generic.IEnumerator GetEnumerator() - { - yield return this; - } + yield return this; + } - public static implicit operator string(AStruct astruct) - { - return ""; - } + public static implicit operator string(AStruct astruct) + { + return ""; } - """; + } + """; - await VerifyCS.VerifyAnalyzerAsync(programWithImplicitCastOperator); - } + await VerifyCS.VerifyAnalyzerAsync(programWithImplicitCastOperator); + } - [Fact] - public Task TypeConversionAllocation_InterpolatedStringWithInt_BoxingWarningAsync() - => VerifyCS.VerifyAnalyzerAsync(""" - using System; - using Roslyn.Utilities; + [Fact] + public Task TypeConversionAllocation_InterpolatedStringWithInt_BoxingWarningAsync() + => VerifyCS.VerifyAnalyzerAsync(""" + using System; + using Roslyn.Utilities; - class Program + class Program + { + [PerformanceSensitive("uri")] + void SomeMethod() { - [PerformanceSensitive("uri")] - void SomeMethod() - { - string s = $"{1}"; - } + string s = $"{1}"; } - """, - // Test0.cs(10,23): warning HAA0601: Value type to reference type conversion causes boxing at call site (here), and unboxing at the callee-site. Consider using generics if applicable + } + """, + // Test0.cs(10,23): warning HAA0601: Value type to reference type conversion causes boxing at call site (here), and unboxing at the callee-site. Consider using generics if applicable #pragma warning disable RS0030 // Do not use banned APIs - VerifyCS.Diagnostic(TypeConversionAllocationAnalyzer.ValueTypeToReferenceTypeConversionRule).WithLocation(9, 23)); + VerifyCS.Diagnostic(TypeConversionAllocationAnalyzer.ValueTypeToReferenceTypeConversionRule).WithLocation(9, 23)); #if false - [Fact] - public void TypeConversionAllocation_InterpolatedStringWithString_NoWarning() - { - var sampleProgram = @"string s = $""{1.ToString()}"";"; + [Fact] + public void TypeConversionAllocation_InterpolatedStringWithString_NoWarning() + { + var sampleProgram = @"string s = $""{1.ToString()}"";"; - var analyser = new TypeConversionAllocationAnalyzer(); - var info = ProcessCode(analyser, sampleProgram, ImmutableArray.Create(SyntaxKind.Interpolation)); + var analyser = new TypeConversionAllocationAnalyzer(); + var info = ProcessCode(analyser, sampleProgram, ImmutableArray.Create(SyntaxKind.Interpolation)); - Assert.Empty(info.Allocations); - } + Assert.Empty(info.Allocations); + } #endif - [Theory] - [InlineData(@"private readonly System.Func fileExists = System.IO.File.Exists;")] - [InlineData(@"private System.Func fileExists { get; } = System.IO.File.Exists;")] - [InlineData(@"private static System.Func fileExists { get; } = System.IO.File.Exists;")] - [InlineData(@"private static readonly System.Func fileExists = System.IO.File.Exists;")] - public Task TypeConversionAllocation_DelegateAssignmentToReadonly_DoNotWarnAsync(string snippet) - => VerifyCS.VerifyAnalyzerAsync($$""" - using System; - using Roslyn.Utilities; - - class Program - { - [PerformanceSensitive("uri")] - {{snippet}} - } - """, - // Test0.cs(8,68): info HeapAnalyzerReadonlyMethodGroupAllocationRule: This will allocate a delegate instance + [Theory] + [InlineData(@"private readonly System.Func fileExists = System.IO.File.Exists;")] + [InlineData(@"private System.Func fileExists { get; } = System.IO.File.Exists;")] + [InlineData(@"private static System.Func fileExists { get; } = System.IO.File.Exists;")] + [InlineData(@"private static readonly System.Func fileExists = System.IO.File.Exists;")] + public Task TypeConversionAllocation_DelegateAssignmentToReadonly_DoNotWarnAsync(string snippet) + => VerifyCS.VerifyAnalyzerAsync($$""" + using System; + using Roslyn.Utilities; + + class Program + { + [PerformanceSensitive("uri")] + {{snippet}} + } + """, + // Test0.cs(8,68): info HeapAnalyzerReadonlyMethodGroupAllocationRule: This will allocate a delegate instance #pragma warning disable RS0030 // Do not use banned APIs - VerifyCS.Diagnostic(TypeConversionAllocationAnalyzer.ReadonlyMethodGroupAllocationRule).WithLocation(7, 68)); + VerifyCS.Diagnostic(TypeConversionAllocationAnalyzer.ReadonlyMethodGroupAllocationRule).WithLocation(7, 68)); - [Fact] - public async Task TypeConversionAllocation_ExpressionBodiedPropertyBoxing_WithBoxingAsync() - { - const string snippet = """ - using System; - using Roslyn.Utilities; - - class Program - { - [PerformanceSensitive("uri")] - object Obj => 1; - } - """; - - await VerifyCS.VerifyAnalyzerAsync(snippet, - // Test0.cs(8,19): warning HAA0601: Value type to reference type conversion causes boxing at call site (here), and unboxing at the callee-site. Consider using generics if applicable + [Fact] + public async Task TypeConversionAllocation_ExpressionBodiedPropertyBoxing_WithBoxingAsync() + { + const string snippet = """ + using System; + using Roslyn.Utilities; + + class Program + { + [PerformanceSensitive("uri")] + object Obj => 1; + } + """; + + await VerifyCS.VerifyAnalyzerAsync(snippet, + // Test0.cs(8,19): warning HAA0601: Value type to reference type conversion causes boxing at call site (here), and unboxing at the callee-site. Consider using generics if applicable #pragma warning disable RS0030 // Do not use banned APIs - VerifyCS.Diagnostic(TypeConversionAllocationAnalyzer.ValueTypeToReferenceTypeConversionRule).WithLocation(7, 19)); + VerifyCS.Diagnostic(TypeConversionAllocationAnalyzer.ValueTypeToReferenceTypeConversionRule).WithLocation(7, 19)); #pragma warning restore RS0030 // Do not use banned APIs - } - - [Fact] - public async Task TypeConversionAllocation_ExpressionBodiedPropertyBoxing_WithoutBoxingAsync() - { - const string snippet = """ - using System; - using Roslyn.Utilities; - - class Program - { - [PerformanceSensitive("uri")] - object Obj => 1.ToString(); - } - """; + } - await VerifyCS.VerifyAnalyzerAsync(snippet); - } + [Fact] + public async Task TypeConversionAllocation_ExpressionBodiedPropertyBoxing_WithoutBoxingAsync() + { + const string snippet = """ + using System; + using Roslyn.Utilities; + + class Program + { + [PerformanceSensitive("uri")] + object Obj => 1.ToString(); + } + """; + + await VerifyCS.VerifyAnalyzerAsync(snippet); + } - [Fact] - public async Task TypeConversionAllocation_ExpressionBodiedPropertyDelegateAsync() - { - const string snippet = """ - using System; - using Roslyn.Utilities; + [Fact] + public async Task TypeConversionAllocation_ExpressionBodiedPropertyDelegateAsync() + { + const string snippet = """ + using System; + using Roslyn.Utilities; - class Program - { - void Function(int i) { } + class Program + { + void Function(int i) { } - [PerformanceSensitive("uri")] - Action Obj => Function; - } - """; + [PerformanceSensitive("uri")] + Action Obj => Function; + } + """; - await VerifyCS.VerifyAnalyzerAsync(snippet, - // Test0.cs(10,24): warning HAA0603: This will allocate a delegate instance + await VerifyCS.VerifyAnalyzerAsync(snippet, + // Test0.cs(10,24): warning HAA0603: This will allocate a delegate instance #pragma warning disable RS0030 // Do not use banned APIs - VerifyCS.Diagnostic(TypeConversionAllocationAnalyzer.MethodGroupAllocationRule).WithLocation(9, 24)); + VerifyCS.Diagnostic(TypeConversionAllocationAnalyzer.MethodGroupAllocationRule).WithLocation(9, 24)); #pragma warning restore RS0030 // Do not use banned APIs - } + } - [Fact] - public async Task TypeConversionAllocation_ExpressionBodiedPropertyExplicitDelegate_NoWarningAsync() - { - // Tests that an explicit delegate creation does not trigger HAA0603. It should be handled by HAA0502. - const string snippet = """ - using System; - using Roslyn.Utilities; + [Fact] + public async Task TypeConversionAllocation_ExpressionBodiedPropertyExplicitDelegate_NoWarningAsync() + { + // Tests that an explicit delegate creation does not trigger HAA0603. It should be handled by HAA0502. + const string snippet = """ + using System; + using Roslyn.Utilities; - class Program - { - void Function(int i) { } + class Program + { + void Function(int i) { } - [PerformanceSensitive("uri")] - Action Obj => new Action(Function); - } - """; + [PerformanceSensitive("uri")] + Action Obj => new Action(Function); + } + """; - await VerifyCS.VerifyAnalyzerAsync(snippet); - } + await VerifyCS.VerifyAnalyzerAsync(snippet); + } - [Fact] - [WorkItem(7995606, "http://stackoverflow.com/questions/7995606/boxing-occurrence-in-c-sharp")] - public Task Converting_any_enumeration_type_to_System_Enum_typeAsync() - => VerifyCS.VerifyAnalyzerAsync(""" - using Roslyn.Utilities; + [Fact] + [WorkItem(7995606, "http://stackoverflow.com/questions/7995606/boxing-occurrence-in-c-sharp")] + public Task Converting_any_enumeration_type_to_System_Enum_typeAsync() + => VerifyCS.VerifyAnalyzerAsync(""" + using Roslyn.Utilities; - enum E { A } + enum E { A } - public class MyClass + public class MyClass + { + [PerformanceSensitive("uri")] + public void SomeMethod() { - [PerformanceSensitive("uri")] - public void SomeMethod() - { - System.Enum box = E.A; - } + System.Enum box = E.A; } - """, - // Test0.cs(11,27): warning HAA0601: Value type to reference type conversion causes boxing at call site (here), and unboxing at the callee-site. Consider using generics if applicable + } + """, + // Test0.cs(11,27): warning HAA0601: Value type to reference type conversion causes boxing at call site (here), and unboxing at the callee-site. Consider using generics if applicable #pragma warning disable RS0030 // Do not use banned APIs - VerifyCS.Diagnostic(TypeConversionAllocationAnalyzer.ValueTypeToReferenceTypeConversionRule).WithLocation(10, 27)); + VerifyCS.Diagnostic(TypeConversionAllocationAnalyzer.ValueTypeToReferenceTypeConversionRule).WithLocation(10, 27)); - [Fact] - [WorkItem(7995606, "http://stackoverflow.com/questions/7995606/boxing-occurrence-in-c-sharp")] - public Task Creating_delegate_from_value_type_instance_methodAsync() - => VerifyCS.VerifyAnalyzerAsync(""" - using System; - using Roslyn.Utilities; + [Fact] + [WorkItem(7995606, "http://stackoverflow.com/questions/7995606/boxing-occurrence-in-c-sharp")] + public Task Creating_delegate_from_value_type_instance_methodAsync() + => VerifyCS.VerifyAnalyzerAsync(""" + using System; + using Roslyn.Utilities; - struct S { public void M() {} } + struct S { public void M() {} } - public class MyClass + public class MyClass + { + [PerformanceSensitive("uri")] + public void SomeMethod() { - [PerformanceSensitive("uri")] - public void SomeMethod() - { - Action box = new S().M; - } + Action box = new S().M; } - """, - // Test0.cs(12,22): warning HAA0603: This will allocate a delegate instance + } + """, + // Test0.cs(12,22): warning HAA0603: This will allocate a delegate instance #pragma warning disable RS0030 // Do not use banned APIs - VerifyCS.Diagnostic(TypeConversionAllocationAnalyzer.MethodGroupAllocationRule).WithLocation(11, 22), + VerifyCS.Diagnostic(TypeConversionAllocationAnalyzer.MethodGroupAllocationRule).WithLocation(11, 22), #pragma warning restore RS0030 // Do not use banned APIs - // Test0.cs(12,22): warning HAA0602: Struct instance method being used for delegate creation, this will result in a boxing instruction + // Test0.cs(12,22): warning HAA0602: Struct instance method being used for delegate creation, this will result in a boxing instruction #pragma warning disable RS0030 // Do not use banned APIs - VerifyCS.Diagnostic(TypeConversionAllocationAnalyzer.DelegateOnStructInstanceRule).WithLocation(11, 22)); + VerifyCS.Diagnostic(TypeConversionAllocationAnalyzer.DelegateOnStructInstanceRule).WithLocation(11, 22)); - [Fact] - public async Task TypeConversionAllocation_NoDiagnosticWhenPassingDelegateAsArgumentAsync() - { - const string snippet = """ - using System; - using Roslyn.Utilities; + [Fact] + public async Task TypeConversionAllocation_NoDiagnosticWhenPassingDelegateAsArgumentAsync() + { + const string snippet = """ + using System; + using Roslyn.Utilities; - struct Foo + struct Foo + { + [PerformanceSensitive("uri")] + void Do(Action process) { - [PerformanceSensitive("uri")] - void Do(Action process) - { - DoMore(process); - } + DoMore(process); + } - void DoMore(Action process) - { - process(); - } + void DoMore(Action process) + { + process(); } - """; - await VerifyCS.VerifyAnalyzerAsync(snippet); - } + } + """; + await VerifyCS.VerifyAnalyzerAsync(snippet); + } - [Fact] - public async Task TypeConversionAllocation_ReportBoxingAllocationForPassingStructInstanceMethodForDelegateConstructorAsync() - { - const string snippet = """ - using System; - using Roslyn.Utilities; + [Fact] + public async Task TypeConversionAllocation_ReportBoxingAllocationForPassingStructInstanceMethodForDelegateConstructorAsync() + { + const string snippet = """ + using System; + using Roslyn.Utilities; - public struct MyStruct + public struct MyStruct + { + [PerformanceSensitive("uri")] + public void Testing() { - [PerformanceSensitive("uri")] - public void Testing() - { - var @struct = new MyStruct(); - @struct.ProcessFunc(new Func(FooObjCall)); - } + var @struct = new MyStruct(); + @struct.ProcessFunc(new Func(FooObjCall)); + } - public void ProcessFunc(Func func) - { - } + public void ProcessFunc(Func func) + { + } - private string FooObjCall(object obj) - { - return obj.ToString(); - } + private string FooObjCall(object obj) + { + return obj.ToString(); } - """; + } + """; - await VerifyCS.VerifyAnalyzerAsync(snippet, - // Test0.cs(11,54): warning HAA0602: Struct instance method being used for delegate creation, this will result in a boxing instruction - VerifyCS.Diagnostic(TypeConversionAllocationAnalyzer.DelegateOnStructInstanceRule).WithSpan(10, 54, 10, 64)); - } + await VerifyCS.VerifyAnalyzerAsync(snippet, + // Test0.cs(11,54): warning HAA0602: Struct instance method being used for delegate creation, this will result in a boxing instruction + VerifyCS.Diagnostic(TypeConversionAllocationAnalyzer.DelegateOnStructInstanceRule).WithSpan(10, 54, 10, 64)); + } - [Fact] - public async Task TypeConversionAllocation_DoNotReportBoxingAllocationForPassingStructStaticMethodForDelegateConstructorAsync() - { - const string snippet = """ - using System; - using Roslyn.Utilities; + [Fact] + public async Task TypeConversionAllocation_DoNotReportBoxingAllocationForPassingStructStaticMethodForDelegateConstructorAsync() + { + const string snippet = """ + using System; + using Roslyn.Utilities; - public struct MyStruct + public struct MyStruct + { + [PerformanceSensitive("uri")] + public void Testing() { - [PerformanceSensitive("uri")] - public void Testing() - { - var @struct = new MyStruct(); - @struct.ProcessFunc(new Func(FooObjCall)); - } + var @struct = new MyStruct(); + @struct.ProcessFunc(new Func(FooObjCall)); + } - public void ProcessFunc(Func func) - { - } + public void ProcessFunc(Func func) + { + } - private static string FooObjCall(object obj) - { - return obj.ToString(); - } + private static string FooObjCall(object obj) + { + return obj.ToString(); } - """; + } + """; - await VerifyCS.VerifyAnalyzerAsync(snippet); - } + await VerifyCS.VerifyAnalyzerAsync(snippet); + } - [Fact] - public async Task TypeConversionAllocation_DoNotReportInlineDelegateAsStructInstanceMethodsAsync() - { - const string snippet = """ - using System; - using Roslyn.Utilities; + [Fact] + public async Task TypeConversionAllocation_DoNotReportInlineDelegateAsStructInstanceMethodsAsync() + { + const string snippet = """ + using System; + using Roslyn.Utilities; - public struct MyStruct + public struct MyStruct + { + [PerformanceSensitive("uri")] + public void Testing() { - [PerformanceSensitive("uri")] - public void Testing() - { - var ints = new[] { 5, 4, 3, 2, 1 }; - Array.Sort(ints, delegate(int x, int y) { return x - y; }); - Array.Sort(ints, (x, y) => x - y); - DoSomething(() => throw new Exception()); - DoSomething(delegate() { throw new Exception(); }); + var ints = new[] { 5, 4, 3, 2, 1 }; + Array.Sort(ints, delegate(int x, int y) { return x - y; }); + Array.Sort(ints, (x, y) => x - y); + DoSomething(() => throw new Exception()); + DoSomething(delegate() { throw new Exception(); }); - DoSomething2(x => throw new Exception()); - } + DoSomething2(x => throw new Exception()); + } - private static void DoSomething(Action action) - { - } + private static void DoSomething(Action action) + { + } - private static void DoSomething2(Action action) - { - } + private static void DoSomething2(Action action) + { } - """; + } + """; - await VerifyCS.VerifyAnalyzerAsync(snippet); - } + await VerifyCS.VerifyAnalyzerAsync(snippet); } } diff --git a/src/roslyn/src/Scripting/Core/ScriptBuilder.cs b/src/roslyn/src/Scripting/Core/ScriptBuilder.cs index f345991323d..68e2708651b 100644 --- a/src/roslyn/src/Scripting/Core/ScriptBuilder.cs +++ b/src/roslyn/src/Scripting/Core/ScriptBuilder.cs @@ -152,10 +152,7 @@ private Func> Build( peStream.Position = 0; - if (pdbStreamOpt != null) - { - pdbStreamOpt.Position = 0; - } + pdbStreamOpt?.Position = 0; var assembly = _assemblyLoader.LoadAssemblyFromStream(peStream, pdbStreamOpt); var runtimeEntryPoint = GetEntryPointRuntimeMethod(entryPoint, assembly); diff --git a/src/roslyn/src/VisualStudio/Core/Def/InheritanceMargin/InheritanceMarginLogger.cs b/src/roslyn/src/VisualStudio/Core/Def/InheritanceMargin/InheritanceMarginLogger.cs index b88af7fc759..3783866bf71 100644 --- a/src/roslyn/src/VisualStudio/Core/Def/InheritanceMargin/InheritanceMarginLogger.cs +++ b/src/roslyn/src/VisualStudio/Core/Def/InheritanceMargin/InheritanceMarginLogger.cs @@ -34,10 +34,7 @@ public static void ReportTelemetry() static m => { var histogramLogAggregator = s_histogramLogAggregator.GetValue(ActionInfo.GetInheritanceMarginMembers); - if (histogramLogAggregator != null) - { - histogramLogAggregator.WriteTelemetryPropertiesTo(m, nameof(ActionInfo.GetInheritanceMarginMembers) + "."); - } + histogramLogAggregator?.WriteTelemetryPropertiesTo(m, nameof(ActionInfo.GetInheritanceMarginMembers) + "."); })); } } diff --git a/src/roslyn/src/VisualStudio/Core/Def/Utilities/TaskItemsEnum.cs b/src/roslyn/src/VisualStudio/Core/Def/Utilities/TaskItemsEnum.cs index d64bf30a8c9..b160cefe8ec 100644 --- a/src/roslyn/src/VisualStudio/Core/Def/Utilities/TaskItemsEnum.cs +++ b/src/roslyn/src/VisualStudio/Core/Def/Utilities/TaskItemsEnum.cs @@ -29,10 +29,7 @@ int IVsEnumTaskItems.Next(uint celt, IVsTaskItem[] rgelt, uint[] pceltFetched) _next += i; - if (pceltFetched != null) - { - pceltFetched[0] = (uint)i; - } + pceltFetched?[0] = (uint)i; return (i == celt) ? VSConstants.S_OK : VSConstants.S_FALSE; } diff --git a/src/roslyn/src/VisualStudio/Core/Impl/SolutionExplorer/AnalyzersCommandHandler.cs b/src/roslyn/src/VisualStudio/Core/Impl/SolutionExplorer/AnalyzersCommandHandler.cs index f1fed730186..278eb376d90 100644 --- a/src/roslyn/src/VisualStudio/Core/Impl/SolutionExplorer/AnalyzersCommandHandler.cs +++ b/src/roslyn/src/VisualStudio/Core/Impl/SolutionExplorer/AnalyzersCommandHandler.cs @@ -185,10 +185,7 @@ private bool ShouldShowAnalyzerContextMenu(IEnumerable items) private void UpdateAnalyzerContextMenu() { - if (_removeMenuItem != null) - { - _removeMenuItem.Enabled = _allowProjectSystemOperations; - } + _removeMenuItem?.Enabled = _allowProjectSystemOperations; } public IContextMenuController DiagnosticContextMenuController @@ -557,10 +554,7 @@ private static void UpdateProjectConfigurationsToUseRuleSetFile(EnvDTE.Project e { var codeAnalysisRuleSetFileProperty = properties?.Item("CodeAnalysisRuleSet"); - if (codeAnalysisRuleSetFileProperty != null) - { - codeAnalysisRuleSetFileProperty.Value = fileName; - } + codeAnalysisRuleSetFileProperty?.Value = fileName; } catch (ArgumentException) { diff --git a/src/roslyn/src/VisualStudio/IntegrationTest/New.IntegrationTests/CSharp/CSharpAddMissingUsingsOnPaste.cs b/src/roslyn/src/VisualStudio/IntegrationTest/New.IntegrationTests/CSharp/CSharpAddMissingUsingsOnPaste.cs index 1b8c8002231..adbe0cef8d5 100644 --- a/src/roslyn/src/VisualStudio/IntegrationTest/New.IntegrationTests/CSharp/CSharpAddMissingUsingsOnPaste.cs +++ b/src/roslyn/src/VisualStudio/IntegrationTest/New.IntegrationTests/CSharp/CSharpAddMissingUsingsOnPaste.cs @@ -14,13 +14,8 @@ namespace Roslyn.VisualStudio.NewIntegrationTests.CSharp; [Trait(Traits.Feature, Traits.Features.AddMissingImports)] -public class CSharpAddMissingUsingsOnPaste : AbstractEditorTest +public sealed class CSharpAddMissingUsingsOnPaste() : AbstractEditorTest(nameof(CSharpAddMissingUsingsOnPaste)) { - public CSharpAddMissingUsingsOnPaste() - : base(nameof(CSharpAddMissingUsingsOnPaste)) - { - } - protected override string LanguageName => LanguageNames.CSharp; [IdeFact] diff --git a/src/roslyn/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/AbstractReferenceFinder.cs b/src/roslyn/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/AbstractReferenceFinder.cs index 88e4c1c58c3..cfb3f834399 100644 --- a/src/roslyn/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/AbstractReferenceFinder.cs +++ b/src/roslyn/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/AbstractReferenceFinder.cs @@ -608,7 +608,17 @@ protected static SymbolUsageInfo GetSymbolUsageInfo( while (syntaxFacts.IsQualifiedName(topNameNode.Parent)) topNameNode = topNameNode.Parent; - var isInNamespaceNameContext = syntaxFacts.IsBaseNamespaceDeclaration(topNameNode.Parent); + var parent = topNameNode?.Parent; + + // typeof/sizeof are a special case where we don't want to return a TypeOrNamespaceUsageInfo, but rather a ValueUsageInfo.Name. + // This brings it in line with nameof(...), making all those operators appear in a similar fashion. + if (parent?.RawKind == syntaxFacts.SyntaxKinds.TypeOfExpression || + parent?.RawKind == syntaxFacts.SyntaxKinds.SizeOfExpression) + { + return new(ValueUsageInfo.Name, typeOrNamespaceUsageInfoOpt: null); + } + + var isInNamespaceNameContext = syntaxFacts.IsBaseNamespaceDeclaration(parent); return syntaxFacts.IsInNamespaceOrTypeContext(topNameNode) ? SymbolUsageInfo.Create(GetTypeOrNamespaceUsageInfo()) : GetSymbolUsageInfoCommon(); @@ -677,18 +687,12 @@ SymbolUsageInfo GetSymbolUsageInfoCommon() if (operation is IObjectCreationOperation) return SymbolUsageInfo.Create(TypeOrNamespaceUsageInfo.ObjectCreation); - switch (operation?.Parent) - { - case INameOfOperation: - case ITypeOfOperation: - case ISizeOfOperation: - return SymbolUsageInfo.Create(ValueUsageInfo.Name); - } + // Note: sizeof/typeof also return 'name', but are handled above in GetSymbolUsageInfo. + if (operation?.Parent is INameOfOperation) + return SymbolUsageInfo.Create(ValueUsageInfo.Name); if (node.IsPartOfStructuredTrivia()) - { return SymbolUsageInfo.Create(ValueUsageInfo.Name); - } var symbolInfo = semanticModel.GetSymbolInfo(node, cancellationToken); if (symbolInfo.Symbol != null) diff --git a/src/roslyn/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Services/SyntaxFacts/CSharpSyntaxKinds.cs b/src/roslyn/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Services/SyntaxFacts/CSharpSyntaxKinds.cs index 5afb9f1eadc..e74bd19a931 100644 --- a/src/roslyn/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Services/SyntaxFacts/CSharpSyntaxKinds.cs +++ b/src/roslyn/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Services/SyntaxFacts/CSharpSyntaxKinds.cs @@ -118,11 +118,13 @@ public int Convert(TSyntaxKind kind) where TSyntaxKind : struct public int ReferenceNotEqualsExpression => (int)SyntaxKind.NotEqualsExpression; public int SimpleAssignmentExpression => (int)SyntaxKind.SimpleAssignmentExpression; public int SimpleMemberAccessExpression => (int)SyntaxKind.SimpleMemberAccessExpression; + public int? SizeOfExpression => (int)SyntaxKind.SizeOfExpression; public int? SuppressNullableWarningExpression => (int)SyntaxKind.SuppressNullableWarningExpression; public int TernaryConditionalExpression => (int)SyntaxKind.ConditionalExpression; public int ThisExpression => (int)SyntaxKind.ThisExpression; public int? ThrowExpression => (int)SyntaxKind.ThrowExpression; public int TupleExpression => (int)SyntaxKind.TupleExpression; + public int TypeOfExpression => (int)SyntaxKind.TypeOfExpression; public int? AndPattern => (int)SyntaxKind.AndPattern; public int? ConstantPattern => (int)SyntaxKind.ConstantPattern; diff --git a/src/roslyn/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Simplification/Simplifiers/CastSimplifier.cs b/src/roslyn/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Simplification/Simplifiers/CastSimplifier.cs index 7f6b771c13f..4e99b8b60e9 100644 --- a/src/roslyn/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Simplification/Simplifiers/CastSimplifier.cs +++ b/src/roslyn/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Simplification/Simplifiers/CastSimplifier.cs @@ -919,7 +919,7 @@ bool IsConditionalCastSafeToRemoveDueToConversionToOtherBranch() return false; // Check if 'y' has the same type as 'z'. - if (!otherSideType.Equals(thisSideRewrittenType)) + if (!otherSideType.Equals(thisSideRewrittenType, SymbolEqualityComparer.IncludeNullability)) return false; // Now check that with the (T) cast removed, that the outer `x ? y : z` is still diff --git a/src/roslyn/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Utilities/TypeStyle/CSharpUseImplicitTypeHelper.cs b/src/roslyn/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Utilities/TypeStyle/CSharpUseImplicitTypeHelper.cs index 5f38dac59b3..e37d16980e7 100644 --- a/src/roslyn/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Utilities/TypeStyle/CSharpUseImplicitTypeHelper.cs +++ b/src/roslyn/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Utilities/TypeStyle/CSharpUseImplicitTypeHelper.cs @@ -122,18 +122,14 @@ SyntaxKind.ForStatement or if (variableDeclaration.Variables is not [{ Initializer.Value: var initializer } variable]) return false; - // Do not suggest var replacement for stackalloc span expressions. - // This will change the bound type from a span to a pointer. - if (!variableDeclaration.Type.IsKind(SyntaxKind.PointerType)) + // Do not suggest var replacement for stackalloc span expressions. This will change the bound type from a + // span to a pointer. Note: this only applies to `var v = stackalloc ...;` If `stackalloc` is anywhere + // lower (including `var v = (stackalloc ...);`), then this is will be a span, and it will be ok to change + // to use 'var'. + if (!variableDeclaration.Type.IsKind(SyntaxKind.PointerType) && + initializer is StackAllocArrayCreationExpressionSyntax) { - var containsStackAlloc = initializer - .DescendantNodesAndSelf(descendIntoChildren: node => node is not AnonymousFunctionExpressionSyntax) - .Any(node => node.IsKind(SyntaxKind.StackAllocArrayCreationExpression)); - - if (containsStackAlloc) - { - return false; - } + return false; } if (AssignmentSupportsStylePreference( diff --git a/src/roslyn/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Extensions/SymbolUsageInfo.cs b/src/roslyn/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Extensions/SymbolUsageInfo.cs index d558d96e273..8f485357cbb 100644 --- a/src/roslyn/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Extensions/SymbolUsageInfo.cs +++ b/src/roslyn/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Extensions/SymbolUsageInfo.cs @@ -2,10 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System; using System.Diagnostics; using System.Runtime.Serialization; -using Roslyn.Utilities; namespace Microsoft.CodeAnalysis; @@ -15,7 +13,7 @@ namespace Microsoft.CodeAnalysis; /// For methods, fields, properties, events, locals and parameters, this corresponds to values from . /// [DataContract] -internal readonly struct SymbolUsageInfo : IEquatable +internal readonly record struct SymbolUsageInfo { public static readonly SymbolUsageInfo None = Create(ValueUsageInfo.None); @@ -45,28 +43,4 @@ public bool IsReadFrom() public bool IsWrittenTo() => ValueUsageInfoOpt.HasValue && ValueUsageInfoOpt.Value.IsWrittenTo(); - - public bool IsNameOnly() - => ValueUsageInfoOpt.HasValue && ValueUsageInfoOpt.Value.IsNameOnly(); - - public override bool Equals(object? obj) - => obj is SymbolUsageInfo && Equals((SymbolUsageInfo)obj); - - public bool Equals(SymbolUsageInfo other) - { - if (ValueUsageInfoOpt.HasValue) - { - return other.ValueUsageInfoOpt.HasValue && - ValueUsageInfoOpt.Value == other.ValueUsageInfoOpt.Value; - } - else - { - RoslynDebug.Assert(TypeOrNamespaceUsageInfoOpt.HasValue); - return other.TypeOrNamespaceUsageInfoOpt.HasValue && - TypeOrNamespaceUsageInfoOpt.Value == other.TypeOrNamespaceUsageInfoOpt.Value; - } - } - - public override int GetHashCode() - => Hash.Combine(((int?)ValueUsageInfoOpt)?.GetHashCode() ?? 0, ((int?)TypeOrNamespaceUsageInfoOpt)?.GetHashCode() ?? 0); } diff --git a/src/roslyn/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Services/SyntaxFacts/ISyntaxKinds.cs b/src/roslyn/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Services/SyntaxFacts/ISyntaxKinds.cs index 71cdf02df85..41981d1cb8d 100644 --- a/src/roslyn/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Services/SyntaxFacts/ISyntaxKinds.cs +++ b/src/roslyn/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Services/SyntaxFacts/ISyntaxKinds.cs @@ -161,11 +161,13 @@ internal interface ISyntaxKinds int ReferenceNotEqualsExpression { get; } int SimpleAssignmentExpression { get; } int SimpleMemberAccessExpression { get; } + int? SizeOfExpression { get; } int? SuppressNullableWarningExpression { get; } int TernaryConditionalExpression { get; } int ThisExpression { get; } int? ThrowExpression { get; } int TupleExpression { get; } + int TypeOfExpression { get; } #endregion diff --git a/src/roslyn/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/VisualBasic/Extensions/ParenthesizedExpressionSyntaxExtensions.vb b/src/roslyn/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/VisualBasic/Extensions/ParenthesizedExpressionSyntaxExtensions.vb index da471f2bace..aa7af3efb79 100644 --- a/src/roslyn/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/VisualBasic/Extensions/ParenthesizedExpressionSyntaxExtensions.vb +++ b/src/roslyn/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/VisualBasic/Extensions/ParenthesizedExpressionSyntaxExtensions.vb @@ -346,6 +346,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Extensions ' Cases: ' (1 + 1) * 8 ' (1 + 1).ToString + ' (1 + 1)?.ToString ' (1 + 1)() If TypeOf expression Is BinaryExpressionSyntax OrElse TypeOf expression Is UnaryExpressionSyntax Then @@ -353,6 +354,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Extensions Dim parentExpression = TryCast(node.Parent, ExpressionSyntax) If parentExpression IsNot Nothing Then If parentExpression.IsKind(SyntaxKind.SimpleMemberAccessExpression) OrElse + parentExpression.IsKind(SyntaxKind.ConditionalAccessExpression) OrElse parentExpression.IsKind(SyntaxKind.InvocationExpression) Then Return False End If diff --git a/src/roslyn/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/VisualBasic/Services/SyntaxFacts/VisualBasicSyntaxKinds.vb b/src/roslyn/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/VisualBasic/Services/SyntaxFacts/VisualBasicSyntaxKinds.vb index 0641f531b5c..104f2d01b47 100644 --- a/src/roslyn/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/VisualBasic/Services/SyntaxFacts/VisualBasicSyntaxKinds.vb +++ b/src/roslyn/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/VisualBasic/Services/SyntaxFacts/VisualBasicSyntaxKinds.vb @@ -120,11 +120,13 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.LanguageService Public ReadOnly Property ReferenceNotEqualsExpression As Integer = SyntaxKind.IsNotExpression Implements ISyntaxKinds.ReferenceNotEqualsExpression Public ReadOnly Property SimpleAssignmentExpression As Integer = SyntaxKind.SimpleAssignmentStatement Implements ISyntaxKinds.SimpleAssignmentExpression Public ReadOnly Property SimpleMemberAccessExpression As Integer = SyntaxKind.SimpleMemberAccessExpression Implements ISyntaxKinds.SimpleMemberAccessExpression + Public ReadOnly Property SizeOfExpression As Integer? Implements ISyntaxKinds.SizeOfExpression Public ReadOnly Property SuppressNullableWarningExpression As Integer? Implements ISyntaxKinds.SuppressNullableWarningExpression Public ReadOnly Property TernaryConditionalExpression As Integer = SyntaxKind.TernaryConditionalExpression Implements ISyntaxKinds.TernaryConditionalExpression Public ReadOnly Property ThisExpression As Integer = SyntaxKind.MeExpression Implements ISyntaxKinds.ThisExpression Public ReadOnly Property ThrowExpression As Integer? Implements ISyntaxKinds.ThrowExpression Public ReadOnly Property TupleExpression As Integer = SyntaxKind.TupleExpression Implements ISyntaxKinds.TupleExpression + Public ReadOnly Property TypeOfExpression As Integer = SyntaxKind.GetTypeExpression Implements ISyntaxKinds.TypeOfExpression Public ReadOnly Property AndPattern As Integer? Implements ISyntaxKinds.AndPattern Public ReadOnly Property ConstantPattern As Integer? Implements ISyntaxKinds.ConstantPattern diff --git a/src/roslyn/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/CodeGeneration/CSharpCodeGenerationHelpers.cs b/src/roslyn/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/CodeGeneration/CSharpCodeGenerationHelpers.cs index 75d972a22f0..12421618da5 100644 --- a/src/roslyn/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/CodeGeneration/CSharpCodeGenerationHelpers.cs +++ b/src/roslyn/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/CodeGeneration/CSharpCodeGenerationHelpers.cs @@ -172,14 +172,15 @@ public static SyntaxList Insert( CSharpCodeGenerationContextInfo info, IList? availableIndices, Func, TDeclaration?>? after = null, - Func, TDeclaration?>? before = null) + Func, TDeclaration?>? before = null, + Func, int, bool>? canPlaceAtIndex = null) where TDeclaration : SyntaxNode { var index = GetInsertionIndex( declarationList, declaration, info, availableIndices, CSharpDeclarationComparer.WithoutNamesInstance, CSharpDeclarationComparer.WithNamesInstance, - after, before); + after, before, canPlaceAtIndex); availableIndices?.Insert(index, true); diff --git a/src/roslyn/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/CodeGeneration/NamedTypeGenerator.cs b/src/roslyn/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/CodeGeneration/NamedTypeGenerator.cs index 31c4d36df88..a97d4b64fd1 100644 --- a/src/roslyn/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/CodeGeneration/NamedTypeGenerator.cs +++ b/src/roslyn/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/CodeGeneration/NamedTypeGenerator.cs @@ -59,7 +59,11 @@ public static CompilationUnitSyntax AddNamedTypeTo( CancellationToken cancellationToken) { var declaration = GenerateNamedTypeDeclaration(service, namedType, CodeGenerationDestination.CompilationUnit, info, cancellationToken); - var members = Insert(destination.Members, declaration, info, availableIndices); + var members = Insert( + destination.Members, declaration, info, availableIndices, + // We're adding a named type to a compilation unit. If there are any global statements, we must place it after them. + after: static members => members.LastOrDefault(m => m is GlobalStatementSyntax), + canPlaceAtIndex: static (members, index) => index >= members.Count || members[index] is not GlobalStatementSyntax); return destination.WithMembers(members); } diff --git a/src/roslyn/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/CodeGeneration/CodeGenerationHelpers.cs b/src/roslyn/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/CodeGeneration/CodeGenerationHelpers.cs index 476a0c10011..1e653b7a55c 100644 --- a/src/roslyn/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/CodeGeneration/CodeGenerationHelpers.cs +++ b/src/roslyn/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/CodeGeneration/CodeGenerationHelpers.cs @@ -193,11 +193,14 @@ public static int GetInsertionIndex( IComparer comparerWithoutNameCheck, IComparer comparerWithNameCheck, Func, TDeclaration?>? after = null, - Func, TDeclaration?>? before = null) + Func, TDeclaration?>? before = null, + Func, int, bool>? canPlaceAtIndex = null) where TDeclaration : SyntaxNode { Contract.ThrowIfTrue(availableIndices != null && availableIndices.Count != declarationList.Count + 1); + canPlaceAtIndex ??= static (_, _) => true; + // Try to strictly obey the after option by inserting immediately after the member containing the location if (info.Context.AfterThisLocation?.SourceTree is { } afterSourceTree && afterSourceTree.FilePath == declarationList.FirstOrDefault()?.SyntaxTree.FilePath) @@ -207,10 +210,8 @@ public static int GetInsertionIndex( { var index = declarationList.IndexOf(afterMember); index = GetPreferredIndex(index + 1, availableIndices, forward: true); - if (index != -1) - { + if (index != -1 && canPlaceAtIndex(declarationList, index)) return index; - } } } diff --git a/src/source-manifest.json b/src/source-manifest.json index d3d733969c8..fcf73c94946 100644 --- a/src/source-manifest.json +++ b/src/source-manifest.json @@ -73,10 +73,10 @@ "commitSha": "ce330d020d1686e80f5ed4aec2e66f12c4f505b5" }, { - "barId": 274992, + "barId": 275167, "path": "roslyn", "remoteUri": "https://github.com/dotnet/roslyn", - "commitSha": "d3571ef089ef13c74ea786dce8ef615916a097cd" + "commitSha": "c1794aa58db74f27cd6bc7afc1b1d72b713f393b" }, { "barId": 273951, From c1dbdfba4372d35494e16ddda21ac8bdf9e0e5dd Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Tue, 15 Jul 2025 07:17:04 -0700 Subject: [PATCH 03/18] [main] Source code updates from dotnet/winforms (#1491) Co-authored-by: dotnet-maestro[bot] --- src/source-manifest.json | 4 +- src/winforms/eng/Version.Details.xml | 98 ++--- src/winforms/eng/Versions.props | 42 +- src/winforms/global.json | 8 +- ...View.CheckedListViewItemCollectionTests.cs | 412 +++++++++++++++++- 5 files changed, 484 insertions(+), 80 deletions(-) diff --git a/src/source-manifest.json b/src/source-manifest.json index fcf73c94946..f4e241cee16 100644 --- a/src/source-manifest.json +++ b/src/source-manifest.json @@ -139,10 +139,10 @@ "commitSha": "7890fbb7f086ae12b11ca85499b18f460c9090dd" }, { - "barId": 274987, + "barId": 275147, "path": "winforms", "remoteUri": "https://github.com/dotnet/winforms", - "commitSha": "d5b62a713f569a578805301a2bc77e7dfe60b36d" + "commitSha": "17857aa725c3d0860f3aff0178d3b14817eb2266" }, { "barId": 274919, diff --git a/src/winforms/eng/Version.Details.xml b/src/winforms/eng/Version.Details.xml index a5b4f3a7479..d0791f836cd 100644 --- a/src/winforms/eng/Version.Details.xml +++ b/src/winforms/eng/Version.Details.xml @@ -6,106 +6,106 @@ Note: if the Uri is a new place, you will need to add a subscription from that p And you can check these with "darc get-dependencies target-repo "winforms" --> - + - + https://github.com/dotnet/dotnet - 86117ef4343bab700dab871c416e55b22848cd52 + 0b032b9f942c1ae8de535a434c4f4a9206fd3339 - + https://github.com/dotnet/dotnet - 86117ef4343bab700dab871c416e55b22848cd52 + 0b032b9f942c1ae8de535a434c4f4a9206fd3339 - + https://github.com/dotnet/dotnet - 86117ef4343bab700dab871c416e55b22848cd52 + 0b032b9f942c1ae8de535a434c4f4a9206fd3339 - + https://github.com/dotnet/dotnet - 86117ef4343bab700dab871c416e55b22848cd52 + 0b032b9f942c1ae8de535a434c4f4a9206fd3339 - + https://github.com/dotnet/dotnet - 86117ef4343bab700dab871c416e55b22848cd52 + 0b032b9f942c1ae8de535a434c4f4a9206fd3339 - + https://github.com/dotnet/dotnet - 86117ef4343bab700dab871c416e55b22848cd52 + 0b032b9f942c1ae8de535a434c4f4a9206fd3339 - + https://github.com/dotnet/dotnet - 86117ef4343bab700dab871c416e55b22848cd52 + 0b032b9f942c1ae8de535a434c4f4a9206fd3339 - + https://github.com/dotnet/dotnet - 86117ef4343bab700dab871c416e55b22848cd52 + 0b032b9f942c1ae8de535a434c4f4a9206fd3339 - + https://github.com/dotnet/dotnet - 86117ef4343bab700dab871c416e55b22848cd52 + 0b032b9f942c1ae8de535a434c4f4a9206fd3339 - + https://github.com/dotnet/dotnet - 86117ef4343bab700dab871c416e55b22848cd52 + 0b032b9f942c1ae8de535a434c4f4a9206fd3339 - + https://github.com/dotnet/dotnet - 86117ef4343bab700dab871c416e55b22848cd52 + 0b032b9f942c1ae8de535a434c4f4a9206fd3339 - + https://github.com/dotnet/dotnet - 86117ef4343bab700dab871c416e55b22848cd52 + 0b032b9f942c1ae8de535a434c4f4a9206fd3339 - + https://github.com/dotnet/dotnet - 86117ef4343bab700dab871c416e55b22848cd52 + 0b032b9f942c1ae8de535a434c4f4a9206fd3339 - + https://github.com/dotnet/dotnet - 86117ef4343bab700dab871c416e55b22848cd52 + 0b032b9f942c1ae8de535a434c4f4a9206fd3339 - + https://github.com/dotnet/dotnet - 86117ef4343bab700dab871c416e55b22848cd52 + 0b032b9f942c1ae8de535a434c4f4a9206fd3339 - + https://github.com/dotnet/dotnet - 86117ef4343bab700dab871c416e55b22848cd52 + 0b032b9f942c1ae8de535a434c4f4a9206fd3339 - + https://github.com/dotnet/dotnet - 86117ef4343bab700dab871c416e55b22848cd52 + 0b032b9f942c1ae8de535a434c4f4a9206fd3339 - + https://github.com/dotnet/dotnet - 86117ef4343bab700dab871c416e55b22848cd52 + 0b032b9f942c1ae8de535a434c4f4a9206fd3339 - + https://github.com/dotnet/dotnet - 86117ef4343bab700dab871c416e55b22848cd52 + 0b032b9f942c1ae8de535a434c4f4a9206fd3339 - + https://github.com/dotnet/dotnet - 86117ef4343bab700dab871c416e55b22848cd52 + 0b032b9f942c1ae8de535a434c4f4a9206fd3339 - + https://github.com/dotnet/dotnet - 86117ef4343bab700dab871c416e55b22848cd52 + 0b032b9f942c1ae8de535a434c4f4a9206fd3339 - + https://github.com/dotnet/dotnet - 86117ef4343bab700dab871c416e55b22848cd52 + 0b032b9f942c1ae8de535a434c4f4a9206fd3339 - + https://github.com/dotnet/dotnet - 86117ef4343bab700dab871c416e55b22848cd52 + 0b032b9f942c1ae8de535a434c4f4a9206fd3339 - + https://github.com/dotnet/dotnet - 86117ef4343bab700dab871c416e55b22848cd52 + 0b032b9f942c1ae8de535a434c4f4a9206fd3339 diff --git a/src/winforms/eng/Versions.props b/src/winforms/eng/Versions.props index fb0e9816687..bd85b1a716a 100644 --- a/src/winforms/eng/Versions.props +++ b/src/winforms/eng/Versions.props @@ -10,30 +10,30 @@ $(MajorVersion).$(MinorVersion).$(PatchVersion) false release - 10.0.0-preview.7.25360.101 - 10.0.0-preview.7.25360.101 + 10.0.0-preview.7.25363.101 + 10.0.0-preview.7.25363.101 - 10.0.0-preview.7.25360.101 - 10.0.0-preview.7.25360.101 + 10.0.0-preview.7.25363.101 + 10.0.0-preview.7.25363.101 5.0.0-preview.7.20320.5 - 10.0.0-preview.7.25360.101 + 10.0.0-preview.7.25363.101 6.1.0-preview.1.24511.1 - 10.0.0-preview.7.25360.101 - 10.0.0-preview.7.25360.101 - 10.0.0-preview.7.25360.101 - 10.0.0-preview.7.25360.101 - 10.0.0-preview.7.25360.101 - 10.0.0-preview.7.25360.101 - 10.0.0-preview.7.25360.101 - 10.0.0-preview.7.25360.101 + 10.0.0-preview.7.25363.101 + 10.0.0-preview.7.25363.101 + 10.0.0-preview.7.25363.101 + 10.0.0-preview.7.25363.101 + 10.0.0-preview.7.25363.101 + 10.0.0-preview.7.25363.101 + 10.0.0-preview.7.25363.101 + 10.0.0-preview.7.25363.101 10.0.0-preview.5.25227.101 - 10.0.0-preview.7.25360.101 - 10.0.0-preview.7.25360.101 - 10.0.0-preview.7.25360.101 - 10.0.0-preview.7.25360.101 - 10.0.0-preview.7.25360.101 + 10.0.0-preview.7.25363.101 + 10.0.0-preview.7.25363.101 + 10.0.0-preview.7.25363.101 + 10.0.0-preview.7.25363.101 + 10.0.0-preview.7.25363.101 @@ -46,9 +46,9 @@ - 10.0.0-beta.25360.101 - 10.0.0-beta.25360.101 - 10.0.0-beta.25360.101 + 10.0.0-beta.25363.101 + 10.0.0-beta.25363.101 + 10.0.0-beta.25363.101 17.4.0-preview-20220707-01 diff --git a/src/winforms/global.json b/src/winforms/global.json index 1b308b40e0c..d9436cc48d5 100644 --- a/src/winforms/global.json +++ b/src/winforms/global.json @@ -21,11 +21,11 @@ } }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "10.0.0-beta.25360.101", - "Microsoft.DotNet.CMake.Sdk": "10.0.0-beta.25360.101", - "Microsoft.DotNet.Helix.Sdk": "10.0.0-beta.25360.101", + "Microsoft.DotNet.Arcade.Sdk": "10.0.0-beta.25363.101", + "Microsoft.DotNet.CMake.Sdk": "10.0.0-beta.25363.101", + "Microsoft.DotNet.Helix.Sdk": "10.0.0-beta.25363.101", "FIX-85B6-MERGE-9C38-CONFLICT": "1.0.0", - "Microsoft.NET.Sdk.IL": "10.0.0-preview.7.25360.101" + "Microsoft.NET.Sdk.IL": "10.0.0-preview.7.25363.101" }, "native-tools": { "cmake": "latest" diff --git a/src/winforms/src/test/unit/System.Windows.Forms/System/Windows/Forms/ListView.CheckedListViewItemCollectionTests.cs b/src/winforms/src/test/unit/System.Windows.Forms/System/Windows/Forms/ListView.CheckedListViewItemCollectionTests.cs index 443838bdb9b..1742a9e71eb 100644 --- a/src/winforms/src/test/unit/System.Windows.Forms/System/Windows/Forms/ListView.CheckedListViewItemCollectionTests.cs +++ b/src/winforms/src/test/unit/System.Windows.Forms/System/Windows/Forms/ListView.CheckedListViewItemCollectionTests.cs @@ -1,15 +1,419 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -#nullable disable +using System.Collections; namespace System.Windows.Forms.Tests; -public class ListView_CheckedListViewItemCollectionTests +public class ListView_CheckedListViewItemCollectionTests : IDisposable { + private readonly ListView _listView; + private readonly ListView.CheckedListViewItemCollection _collection; + + public ListView_CheckedListViewItemCollectionTests() + { + _listView = new ListView(); + _collection = new ListView.CheckedListViewItemCollection(_listView); + } + + public void Dispose() => _listView.Dispose(); + + [WinFormsFact] + public void CheckedListViewItemCollection_Ctor_OwnerIsNull_ThrowsArgumentNullException() => + Assert.Throws("owner", () => new ListView.CheckedListViewItemCollection(null!)); + + [WinFormsFact] + public void Count_ReturnsCheckedItemCount_WhenNotVirtualMode() + { + _listView.CheckBoxes = true; + _listView.Items.AddRange([ + new ListViewItem { Checked = true }, + new ListViewItem { Checked = false }, + new ListViewItem { Checked = true } + ]); + + _collection.Count.Should().Be(2); + } + + [WinFormsFact] + public void Count_ThrowsInvalidOperationException_WhenVirtualMode() + { + _listView.CheckBoxes = true; + _listView.VirtualMode = true; + + Action act = () => { int _ = _collection.Count; }; + + act.Should().Throw(); + } + + [WinFormsFact] + public void Indexer_ReturnsCheckedItem_ByIndex() + { + _listView.CheckBoxes = true; + ListViewItem item1 = new() { Name = "a", Checked = false }; + ListViewItem item2 = new() { Name = "b", Checked = true }; + ListViewItem item3 = new() { Name = "c", Checked = true }; + _listView.Items.AddRange([item1, item2, item3]); + + _collection[0].Should().Be(item2); + _collection[1].Should().Be(item3); + } + + [WinFormsFact] + public void Indexer_ThrowsInvalidOperationException_WhenVirtualMode() + { + _listView.CheckBoxes = true; + _listView.VirtualMode = true; + + Action act = () => { var _ = _collection[0]; }; + + act.Should().Throw(); + } + + [WinFormsFact] + public void IList_Indexer_Get_ReturnsCheckedItem() + { + _listView.CheckBoxes = true; + ListViewItem item1 = new() { Checked = false }; + ListViewItem item2 = new() { Checked = true }; + _listView.Items.AddRange([item1, item2]); + IList iList = _collection; + + iList[0].Should().Be(item2); + } + + [WinFormsFact] + public void IList_Indexer_Set_ThrowsNotSupportedException() + { + IList iList = _collection; + + Action act = () => iList[0] = new ListViewItem(); + + act.Should().Throw(); + } + + [WinFormsFact] + public void StringIndexer_ReturnsCheckedItem_ByKey() + { + _listView.CheckBoxes = true; + ListViewItem item1 = new() { Name = "foo", Checked = true }; + ListViewItem item2 = new() { Name = "bar", Checked = true }; + _listView.Items.AddRange([item1, item2]); + + _collection["foo"].Should().Be(item1); + _collection["bar"].Should().Be(item2); + } + + [WinFormsFact] + public void StringIndexer_ReturnsNull_ForNullOrEmptyKey() + { + _listView.CheckBoxes = true; + + _collection[null].Should().BeNull(); + _collection[string.Empty].Should().BeNull(); + } + + [WinFormsFact] + public void StringIndexer_ReturnsNull_IfKeyNotFound() + { + _listView.CheckBoxes = true; + ListViewItem item = new() { Name = "foo", Checked = true }; + _listView.Items.Add(item); + + _collection["bar"].Should().BeNull(); + } + + [WinFormsFact] + public void StringIndexer_ThrowsInvalidOperationException_WhenVirtualMode() + { + _listView.CheckBoxes = true; + _listView.VirtualMode = true; + + Action act = () => { var _ = _collection["foo"]; }; + + act.Should().Throw(); + } + + [WinFormsFact] + public void ICollection_SyncRoot_ReturnsSelf() + { + ListView.CheckedListViewItemCollection syncRoot = (ListView.CheckedListViewItemCollection)((ICollection)_collection).SyncRoot; + + syncRoot.Should().BeSameAs(_collection); + } + + [WinFormsFact] + public void ICollection_IsSynchronized_IsFalse() + { + bool isSynchronized = ((ICollection)_collection).IsSynchronized; + + isSynchronized.Should().BeFalse(); + } + + [WinFormsFact] + public void IList_IsFixedSize_IsTrue() + { + bool isFixedSize = ((IList)_collection).IsFixedSize; + + isFixedSize.Should().BeTrue(); + } + + [WinFormsFact] + public void IsReadOnly_IsTrue() + { + _collection.IsReadOnly.Should().BeTrue(); + } + + [WinFormsTheory] + [InlineData(true, true, true)] // Checked and owned + [InlineData(false, true, false)] // Not checked but owned + [InlineData(true, false, false)] // Checked but not owned + public void Contains_ReturnsExpected_BasedOnCheckedAndOwnership(bool isChecked, bool isOwned, bool expected) + { + using ListView listView2 = new(); + _listView.CheckBoxes = true; + listView2.CheckBoxes = true; + + ListViewItem item = new() { Checked = isChecked }; + if (isOwned) + { + _listView.Items.Add(item); + } + else + { + listView2.Items.Add(item); + } + + _collection.Contains(item).Should().Be(expected); + } + + [WinFormsFact] + public void Contains_ThrowsInvalidOperationException_WhenVirtualMode() + { + _listView.VirtualMode = true; + ListViewItem item = new(); + + Action act = () => _collection.Contains(item); + + act.Should().Throw(); + } + + [WinFormsFact] + public void IList_Contains_ReturnsTrue_IfListViewItemIsCheckedAndOwned() + { + _listView.CheckBoxes = true; + ListViewItem item = new() { Checked = true }; + _listView.Items.Add(item); + IList iList = _collection; + + iList.Contains(item).Should().BeTrue(); + } + + [WinFormsFact] + public void IList_Contains_ReturnsFalse_IfNotListViewItem() + { + IList iList = _collection; + + iList.Contains("not an item").Should().BeFalse(); + } + + [WinFormsFact] + public void IList_Contains_ThrowsInvalidOperationException_WhenVirtualMode() + { + _listView.VirtualMode = true; + IList iList = _collection; + + Action act = () => iList.Contains(new ListViewItem()); + + act.Should().Throw(); + } + + [WinFormsTheory] + [InlineData("foo", true)] + [InlineData("bar", false)] + [InlineData(null, false)] + [InlineData("", false)] + public void ContainsKey_ReturnsExpected(string? key, bool expected) + { + _listView.CheckBoxes = true; + ListViewItem item = new() { Name = "foo", Checked = true }; + _listView.Items.Add(item); + + _collection.ContainsKey(key).Should().Be(expected); + } + + [WinFormsFact] + public void ContainsKey_ThrowsInvalidOperationException_WhenVirtualMode() + { + _listView.VirtualMode = true; + + Action act = () => _collection.ContainsKey("foo"); + + act.Should().Throw(); + } + + [WinFormsFact] + public void IndexOf_ReturnsIndex_IfItemIsCheckedAndOwned() + { + _listView.CheckBoxes = true; + ListViewItem item1 = new() { Checked = true }; + ListViewItem item2 = new() { Checked = true }; + _listView.Items.AddRange([item1, item2]); + + _collection.IndexOf(item2).Should().Be(1); + } + + [WinFormsFact] + public void IndexOf_ReturnsMinusOne_IfItemIsNotChecked() + { + _listView.CheckBoxes = true; + ListViewItem item = new() { Checked = false }; + _listView.Items.Add(item); + + _collection.IndexOf(item).Should().Be(-1); + } + + [WinFormsFact] + public void IndexOf_ThrowsInvalidOperationException_WhenVirtualMode() + { + _listView.VirtualMode = true; + + Action act = () => _collection.IndexOf(new ListViewItem()); + + act.Should().Throw(); + } + + [WinFormsFact] + public void IndexOfKey_ReturnsIndex_IfKeyExists() + { + _listView.CheckBoxes = true; + ListViewItem item1 = new() { Name = "foo", Checked = true }; + ListViewItem item2 = new() { Name = "bar", Checked = true }; + _listView.Items.AddRange([item1, item2]); + + _collection.IndexOfKey("bar").Should().Be(1); + } + + [WinFormsFact] + public void IndexOfKey_ReturnsMinusOne_IfKeyIsNullOrEmpty() + { + _listView.CheckBoxes = true; + + _collection.IndexOfKey(null).Should().Be(-1); + _collection.IndexOfKey(string.Empty).Should().Be(-1); + } + [WinFormsFact] - public void CheckedListViewItemCollection_Ctor_OwnerIsNull_ThrowsArgumentNullException() + public void IndexOfKey_ThrowsInvalidOperationException_WhenVirtualMode() { - Assert.Throws("owner", () => { new ListView.CheckedListViewItemCollection(null); }); + _listView.VirtualMode = true; + + Action act = () => _collection.IndexOfKey("foo"); + + act.Should().Throw(); + } + + [WinFormsFact] + public void IList_IndexOf_ReturnsIndex_IfListViewItemIsCheckedAndOwned() + { + _listView.CheckBoxes = true; + ListViewItem item1 = new() { Checked = true }; + ListViewItem item2 = new() { Checked = true }; + _listView.Items.AddRange([item1, item2]); + IList iList = _collection; + + iList.IndexOf(item2).Should().Be(1); + } + + [WinFormsFact] + public void IList_IndexOf_ReturnsMinusOne_IfNotListViewItem() + { + IList iList = _collection; + + iList.IndexOf("not an item").Should().Be(-1); + } + + [WinFormsFact] + public void IList_IndexOf_ThrowsInvalidOperationException_WhenVirtualMode() + { + _listView.VirtualMode = true; + IList iList = _collection; + + Action act = () => iList.IndexOf(new ListViewItem()); + + act.Should().Throw(); + } + + [WinFormsTheory] + [InlineData("Add")] + [InlineData("Clear")] + [InlineData("Insert")] + [InlineData("Remove")] + [InlineData("RemoveAt")] + public void IList_Methods_ThrowNotSupportedException(string methodName) + { + IList iList = _collection; + + Action act = methodName switch + { + "Add" => () => iList.Add(new ListViewItem()), + "Clear" => iList.Clear, + "Insert" => () => iList.Insert(0, new ListViewItem()), + "Remove" => () => iList.Remove(new ListViewItem()), + "RemoveAt" => () => iList.RemoveAt(0), + _ => throw new ArgumentException($"Invalid method name: {methodName}", nameof(methodName)) + }; + + act.Should().Throw(); + } + + [WinFormsFact] + public void CopyTo_CopiesCheckedItems() + { + _listView.CheckBoxes = true; + ListViewItem item1 = new() { Checked = true }; + ListViewItem item2 = new() { Checked = false }; + ListViewItem item3 = new() { Checked = true }; + _listView.Items.AddRange([item1, item2, item3]); + ListViewItem[] array = new ListViewItem[2]; + + _collection.CopyTo(array, 0); + + array.Should().Equal(item1, item3); + } + + [WinFormsFact] + public void CopyTo_ThrowsInvalidOperationException_WhenVirtualMode() + { + _listView.VirtualMode = true; + ListViewItem[] array = new ListViewItem[1]; + + Action act = () => _collection.CopyTo(array, 0); + + act.Should().Throw(); + } + + [WinFormsFact] + public void GetEnumerator_EnumeratesCheckedItems() + { + _listView.CheckBoxes = true; + ListViewItem item1 = new() { Checked = true }; + ListViewItem item2 = new() { Checked = false }; + ListViewItem item3 = new() { Checked = true }; + _listView.Items.AddRange([item1, item2, item3]); + + ListViewItem[] items = _collection.Cast().ToArray(); + + items.Should().Equal(item1, item3); + } + + [WinFormsFact] + public void GetEnumerator_ThrowsInvalidOperationException_WhenVirtualMode() + { + _listView.VirtualMode = true; + + Action act = () => _collection.GetEnumerator(); + + act.Should().Throw(); } } From e1e0588480f40481fef9a26feea14009c53b85a2 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Tue, 15 Jul 2025 07:17:43 -0700 Subject: [PATCH 04/18] [main] Source code updates from dotnet/templating (#1493) Co-authored-by: dotnet-maestro[bot] --- src/source-manifest.json | 4 ++-- src/templating/eng/Version.Details.xml | 10 +++++----- src/templating/eng/Versions.props | 2 +- src/templating/global.json | 14 ++++++++++++-- .../Program.cs | 5 +---- 5 files changed, 21 insertions(+), 14 deletions(-) diff --git a/src/source-manifest.json b/src/source-manifest.json index f4e241cee16..acbb0775789 100644 --- a/src/source-manifest.json +++ b/src/source-manifest.json @@ -121,10 +121,10 @@ "commitSha": "66c6797a1e9a9346d5f6de3f9edaecad6e4350d0" }, { - "barId": 274065, + "barId": 275177, "path": "templating", "remoteUri": "https://github.com/dotnet/templating", - "commitSha": "57150459685ad38272234d96c17036c2cd2f3b96" + "commitSha": "43d52c423e7ed37cf59a01629f9bace5c6bf6f96" }, { "barId": 272429, diff --git a/src/templating/eng/Version.Details.xml b/src/templating/eng/Version.Details.xml index 6149d98c1bc..0739db91bad 100644 --- a/src/templating/eng/Version.Details.xml +++ b/src/templating/eng/Version.Details.xml @@ -1,16 +1,16 @@ - + - + https://github.com/dotnet/dotnet - eaa19c281d34580a8168cff9ce1e7337da8bfe4f + 0b032b9f942c1ae8de535a434c4f4a9206fd3339 - + https://github.com/dotnet/dotnet - eaa19c281d34580a8168cff9ce1e7337da8bfe4f + 0b032b9f942c1ae8de535a434c4f4a9206fd3339 diff --git a/src/templating/eng/Versions.props b/src/templating/eng/Versions.props index 8899b047c4e..cfad649c188 100644 --- a/src/templating/eng/Versions.props +++ b/src/templating/eng/Versions.props @@ -15,7 +15,7 @@ 9.0.3 - 2.0.0-beta6.25351.106 + 2.0.0-beta7.25363.101 9.0.3 9.0.3 9.0.3 diff --git a/src/templating/global.json b/src/templating/global.json index eed21e61148..2a7fe81c5c9 100644 --- a/src/templating/global.json +++ b/src/templating/global.json @@ -1,8 +1,18 @@ { + "sdk": { + "version": "10.0.100-preview.7.25322.101", + "allowPrerelease": true, + "rollForward": "latestFeature", + "paths": [ + ".dotnet", + "$host$" + ], + "errorMessage": "The required .NET SDK wasn't found. Please run ./eng/common/dotnet.cmd/sh to install it." + }, "tools": { - "dotnet": "10.0.100-preview.6.25315.102" + "dotnet": "10.0.100-preview.7.25322.101" }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "10.0.0-beta.25351.106" + "Microsoft.DotNet.Arcade.Sdk": "10.0.0-beta.25363.101" } } diff --git a/src/templating/tools/Microsoft.TemplateEngine.Authoring.CLI/Program.cs b/src/templating/tools/Microsoft.TemplateEngine.Authoring.CLI/Program.cs index 00a3597b35d..8656226e120 100644 --- a/src/templating/tools/Microsoft.TemplateEngine.Authoring.CLI/Program.cs +++ b/src/templating/tools/Microsoft.TemplateEngine.Authoring.CLI/Program.cs @@ -16,10 +16,7 @@ internal static Task Main(string[] args) rootCommand.Subcommands.Add(new VerifyCommand()); rootCommand.Subcommands.Add(new ValidateCommand()); - return rootCommand.Parse(args, new CommandLineConfiguration(rootCommand) - { - EnablePosixBundling = false, - }).InvokeAsync(); + return rootCommand.Parse(args, new() { EnablePosixBundling = false }).InvokeAsync(); } } } From 68af331e619fb03baee61b98a185e8d1a98c3767 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Tue, 15 Jul 2025 07:18:05 -0700 Subject: [PATCH 05/18] [main] Source code updates from dotnet/razor (#1492) Co-authored-by: dotnet-maestro[bot] --- src/razor/eng/Versions.props | 2 +- src/razor/eng/config/PublishData.json | 13 +++++++++++-- src/source-manifest.json | 4 ++-- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/razor/eng/Versions.props b/src/razor/eng/Versions.props index c5567b25ea5..b363b6efa43 100644 --- a/src/razor/eng/Versions.props +++ b/src/razor/eng/Versions.props @@ -30,7 +30,7 @@ imported. This OK because we want to just have an obvious salt for a local build. --> - 17.15.1 + 17.15.2 17.15 $(AddinMajorVersion) $(AddinVersion).$(OfficialBuildId) diff --git a/src/razor/eng/config/PublishData.json b/src/razor/eng/config/PublishData.json index f43f477c561..f7242854cd7 100644 --- a/src/razor/eng/config/PublishData.json +++ b/src/razor/eng/config/PublishData.json @@ -28,8 +28,8 @@ "NonShipping" ], "vsBranch": "main", - "insertionCreateDraftPR": false, - "insertionTitlePrefix": "[d17.15 P1]" + "insertionCreateDraftPR": true, + "insertionTitlePrefix": "[dNext.1]" }, "release/dev17.6": { "nugetKind": [ @@ -107,6 +107,15 @@ "vsBranch": "rel/d17.14", "insertionCreateDraftPR": false, "insertionTitlePrefix": "[d17.14 P3]" + }, + "release/dev-next": { + "nugetKind": [ + "Shipping", + "NonShipping" + ], + "vsBranch": "main", + "insertionCreateDraftPR": false, + "insertionTitlePrefix": "[dNext]" } } } diff --git a/src/source-manifest.json b/src/source-manifest.json index acbb0775789..e8601978bd2 100644 --- a/src/source-manifest.json +++ b/src/source-manifest.json @@ -67,10 +67,10 @@ "commitSha": "772ee13d2bafaa1414d90dbfbd77e0941115ef19" }, { - "barId": 274804, + "barId": 275165, "path": "razor", "remoteUri": "https://github.com/dotnet/razor", - "commitSha": "ce330d020d1686e80f5ed4aec2e66f12c4f505b5" + "commitSha": "88d10f21004784390b5e220607bd4fa6ebfe1301" }, { "barId": 275167, From 44bd674e23071b1a59ec51d3a019fcff75634338 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Tue, 15 Jul 2025 07:36:29 -0700 Subject: [PATCH 06/18] [main] Source code updates from dotnet/aspnetcore (#1494) Co-authored-by: dotnet-maestro[bot] --- src/aspnetcore/eng/Version.Details.xml | 20 +- src/aspnetcore/eng/Versions.props | 10 +- ...bAssemblyJSObjectReferenceJsonConverter.cs | 6 + .../JSObjectReferenceJsonConverterTest.cs | 13 + .../NoInteractivityTest.cs | 17 +- .../ServerRenderingTests/RedirectionTest.cs | 125 +++-- .../test/E2ETest/Tests/InteropTest.cs | 18 +- .../BasicTestApp/InteropComponent.razor | 180 +++++-- .../BasicTestApp/wwwroot/js/jsinteroptests.js | 3 +- .../RedirectionNotFound-SSR-streaming.razor | 2 +- .../NotFound/RedirectionNotFound-SSR.razor | 7 +- .../RedirectionNotFoundComponent.razor | 4 +- .../src/src/Microsoft.JSInterop.ts | 8 +- .../src/test/CallDispatcher.test.ts | 51 ++ .../JSObjectReferenceJsonConverter.cs | 6 + .../JSObjectReferenceJsonConverterTest.cs | 13 + .../EndpointMetadataApiDescriptionProvider.cs | 16 +- ...pointMetadataApiDescriptionProviderTest.cs | 104 ++++ .../gen/XmlCommentGenerator.Emitter.cs | 33 +- .../OpenApi/gen/XmlCommentGenerator.Parser.cs | 35 +- .../XmlCommentDocumentationIdTests.cs | 90 ++++ ...ApiXmlCommentSupport.generated.verified.cs | 33 +- ...ApiXmlCommentSupport.generated.verified.cs | 33 +- ...ApiXmlCommentSupport.generated.verified.cs | 65 ++- ...ApiXmlCommentSupport.generated.verified.cs | 41 +- ...ApiXmlCommentSupport.generated.verified.cs | 65 ++- ...ApiXmlCommentSupport.generated.verified.cs | 33 +- ...ApiXmlCommentSupport.generated.verified.cs | 499 ++++++++++++++++++ src/source-manifest.json | 4 +- 29 files changed, 1353 insertions(+), 181 deletions(-) create mode 100644 src/aspnetcore/src/OpenApi/test/Microsoft.AspNetCore.OpenApi.SourceGenerators.Tests/XmlCommentDocumentationIdTests.cs create mode 100644 src/aspnetcore/src/OpenApi/test/Microsoft.AspNetCore.OpenApi.SourceGenerators.Tests/snapshots/XmlCommentDocumentationIdTests.CanMergeXmlCommentsWithDifferentDocumentationIdFormats#OpenApiXmlCommentSupport.generated.verified.cs diff --git a/src/aspnetcore/eng/Version.Details.xml b/src/aspnetcore/eng/Version.Details.xml index ddf715d8e44..092da0082d3 100644 --- a/src/aspnetcore/eng/Version.Details.xml +++ b/src/aspnetcore/eng/Version.Details.xml @@ -420,25 +420,25 @@ https://github.com/nuget/nuget.client 8fef55f5a55a3b4f2c96cd1a9b5ddc51d4b927f8 - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - 86968b14b5c2ba5104d205665c76c22544c067f6 + 54bab2dbb7652269d9ae0758de122f933b254561 - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - 86968b14b5c2ba5104d205665c76c22544c067f6 + 54bab2dbb7652269d9ae0758de122f933b254561 - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - 86968b14b5c2ba5104d205665c76c22544c067f6 + 54bab2dbb7652269d9ae0758de122f933b254561 - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - 86968b14b5c2ba5104d205665c76c22544c067f6 + 54bab2dbb7652269d9ae0758de122f933b254561 - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - 86968b14b5c2ba5104d205665c76c22544c067f6 + 54bab2dbb7652269d9ae0758de122f933b254561 diff --git a/src/aspnetcore/eng/Versions.props b/src/aspnetcore/eng/Versions.props index d46e69b58fe..f44e9ed54b4 100644 --- a/src/aspnetcore/eng/Versions.props +++ b/src/aspnetcore/eng/Versions.props @@ -182,11 +182,11 @@ 3.2.0-preview.25358.102 - 1.0.0-prerelease.25324.1 - 1.0.0-prerelease.25324.1 - 1.0.0-prerelease.25324.1 - 1.0.0-prerelease.25324.1 - 1.0.0-prerelease.25324.1 + 1.0.0-prerelease.25363.1 + 1.0.0-prerelease.25363.1 + 1.0.0-prerelease.25363.1 + 1.0.0-prerelease.25363.1 + 1.0.0-prerelease.25363.1 float/double casts into helper calls. else if (varTypeIsFloating(dstType) && varTypeIsLong(srcType)) @@ -3043,7 +3029,7 @@ GenTree* Compiler::fgMorphIndexAddr(GenTreeIndexAddr* indexAddr) } #endif // TARGET_64BIT - GenTree* arrLen = gtNewArrLen(TYP_INT, arrRef, (int)indexAddr->gtLenOffset, compCurBB); + GenTree* arrLen = gtNewArrLen(TYP_INT, arrRef, (int)indexAddr->gtLenOffset); if (bndsChkType != TYP_INT) { @@ -3757,7 +3743,7 @@ GenTree* Compiler::fgMorphExpandInstanceField(GenTree* tree, MorphAddrContext* m } GenTree* lclVar = gtNewLclvNode(lclNum, objRefType); - GenTree* nullchk = gtNewNullCheck(lclVar, compCurBB); + GenTree* nullchk = gtNewNullCheck(lclVar); nullchk->SetHasOrderingSideEffect(); @@ -5273,7 +5259,7 @@ GenTree* Compiler::fgMorphTailCallViaHelpers(GenTreeCall* call, CORINFO_TAILCALL { // COMMA(tmp = "this", deref(tmp)) GenTree* tmp = gtNewLclvNode(lclNum, objp->TypeGet()); - GenTree* nullcheck = gtNewNullCheck(tmp, compCurBB); + GenTree* nullcheck = gtNewNullCheck(tmp); doBeforeStoreArgsStub = gtNewOperNode(GT_COMMA, TYP_VOID, doBeforeStoreArgsStub, nullcheck); } @@ -5289,7 +5275,7 @@ GenTree* Compiler::fgMorphTailCallViaHelpers(GenTreeCall* call, CORINFO_TAILCALL if (callNeedsNullCheck) { // deref("this") - doBeforeStoreArgsStub = gtNewNullCheck(objp, compCurBB); + doBeforeStoreArgsStub = gtNewNullCheck(objp); if (stubNeedsThisPtr) { @@ -5829,7 +5815,7 @@ void Compiler::fgMorphTailCallViaJitHelper(GenTreeCall* call) // COMMA(tmp = "this", deref(tmp)) GenTree* tmp = gtNewLclvNode(lclNum, vt); - GenTree* nullcheck = gtNewNullCheck(tmp, compCurBB); + GenTree* nullcheck = gtNewNullCheck(tmp); store = gtNewOperNode(GT_COMMA, TYP_VOID, store, nullcheck); // COMMA(COMMA(tmp = "this", deref(tmp)), tmp) @@ -5838,7 +5824,7 @@ void Compiler::fgMorphTailCallViaJitHelper(GenTreeCall* call) else { // thisPtr = COMMA(deref("this"), "this") - GenTree* nullcheck = gtNewNullCheck(thisPtr, compCurBB); + GenTree* nullcheck = gtNewNullCheck(thisPtr); thisPtr = gtNewOperNode(GT_COMMA, vt, nullcheck, gtClone(objp, true)); } @@ -6358,7 +6344,7 @@ GenTree* Compiler::fgMorphCall(GenTreeCall* call) assert(call->gtArgs.CountArgs() >= 1); GenTree* objPtr = call->gtArgs.GetArgByIndex(0)->GetNode(); - GenTree* nullCheck = gtNewNullCheck(objPtr, compCurBB); + GenTree* nullCheck = gtNewNullCheck(objPtr); return fgMorphTree(nullCheck); } @@ -11335,12 +11321,105 @@ GenTree* Compiler::fgMorphHWIntrinsicRequired(GenTreeHWIntrinsic* tree) if (tree->isCommutativeHWIntrinsic()) { assert(tree->GetOperandCount() == 2); + GenTree*& op1 = tree->Op(1); + GenTree*& op2 = tree->Op(2); if (op1->OperIsConst()) { // Move constants from op1 to op2 for commutative operations - std::swap(op1, tree->Op(2)); + std::swap(op1, op2); + } + + if (((oper == GT_EQ) || (oper == GT_NE)) && op1->OperIsHWIntrinsic() && op2->IsCnsVec()) + { + GenTreeHWIntrinsic* op1Intrinsic = op1->AsHWIntrinsic(); + NamedIntrinsic op1IntrinsicId = op1Intrinsic->GetHWIntrinsicId(); + var_types op1Type = op1Intrinsic->TypeGet(); + + if (HWIntrinsicInfo::ReturnsPerElementMask(op1IntrinsicId) && + (genTypeSize(simdBaseType) == genTypeSize(op1Intrinsic->GetSimdBaseType()))) + { + // This optimization is only safe if we know the other node produces + // AllBitsSet or Zero per element and if the outer comparison is the + // same size as what the other node produces for its mask + + bool reverseCond = false; + + if (oper == GT_EQ) + { + // Handle `Mask == Zero` and `Zero == Mask` for integral types + if (op2->IsVectorZero()) + { + reverseCond = true; + } + } + else if (oper == GT_NE) + { + // Handle `Mask != AllBitsSet` and `AllBitsSet != Mask` for integral types + if (op2->IsVectorAllBitsSet()) + { + reverseCond = true; + } + } + + if (reverseCond) + { + GenTree* newNode = nullptr; + + if (op1Intrinsic->OperIsConvertVectorToMask()) + { +#if defined(TARGET_XARCH) + op1 = op1Intrinsic->Op(1); +#elif defined(TARGET_ARM64) + op1 = op1Intrinsic->Op(2); + DEBUG_DESTROY_NODE(op1Intrinsic->Op(1)); +#else +#error Unsupported platform +#endif // !TARGET_XARCH && !TARGET_ARM64 + + op1Type = op1->TypeGet(); + DEBUG_DESTROY_NODE(op1Intrinsic); + } + + if (op1Type == TYP_MASK) + { +#if defined(TARGET_XARCH) + newNode = gtNewSimdHWIntrinsicNode(op1Type, op1, NI_AVX512_NotMask, simdBaseJitType, simdSize); +#endif // TARGET_XARCH + } + else + { + newNode = gtNewSimdUnOpNode(GT_NOT, op1Type, op1, simdBaseJitType, simdSize); + +#if defined(TARGET_XARCH) + newNode->AsHWIntrinsic()->Op(2)->SetMorphed(this); +#endif // TARGET_XARCH + } + + if (newNode != nullptr) + { + DEBUG_DESTROY_NODE(op2); + DEBUG_DESTROY_NODE(tree); + + if (op1Type != retType) + { + newNode = fgMorphHWIntrinsicRequired(newNode->AsHWIntrinsic()); + + if (retType == TYP_MASK) + { + newNode = gtNewSimdCvtVectorToMaskNode(retType, newNode, simdBaseJitType, simdSize); + } + else + { + newNode = gtNewSimdCvtMaskToVectorNode(retType, newNode, simdBaseJitType, simdSize); + } + } + + return fgMorphHWIntrinsicRequired(newNode->AsHWIntrinsic()); + } + } + } } } else if (GenTree::OperIsCompare(oper)) @@ -11398,20 +11477,15 @@ GenTree* Compiler::fgMorphHWIntrinsicRequired(GenTreeHWIntrinsic* tree) break; } - FloatComparisonMode mode = static_cast(op3->AsIntConCommon()->IntegralValue()); - + FloatComparisonMode mode = static_cast(op3->AsIntConCommon()->IntegralValue()); FloatComparisonMode newMode = mode; switch (mode) { case FloatComparisonMode::UnorderedEqualNonSignaling: - case FloatComparisonMode::OrderedFalseNonSignaling: case FloatComparisonMode::OrderedNotEqualNonSignaling: - case FloatComparisonMode::UnorderedTrueNonSignaling: case FloatComparisonMode::UnorderedEqualSignaling: - case FloatComparisonMode::OrderedFalseSignaling: case FloatComparisonMode::OrderedNotEqualSignaling: - case FloatComparisonMode::UnorderedTrueSignaling: { tree->Op(1) = op2; tree->Op(2) = op1; @@ -15429,13 +15503,13 @@ bool Compiler::fgMorphArrayOpsStmt(MorphMDArrayTempCache* pTempCache, BasicBlock assert((idx->gtFlags & GTF_ALL_EFFECT) == 0); // We should have taken care of side effects earlier. GenTreeMDArr* const mdArrLowerBound = - m_compiler->gtNewMDArrLowerBound(m_compiler->gtNewLclvNode(arrLcl, TYP_REF), i, rank, m_block); + m_compiler->gtNewMDArrLowerBound(m_compiler->gtNewLclvNode(arrLcl, TYP_REF), i, rank); // unsigned effIdxLcl = m_compiler->lvaGrabTemp(true DEBUGARG("MD array effective index")); unsigned effIdxLcl = m_pTempCache->GrabTemp(TYP_INT); GenTree* const effIndex = m_compiler->gtNewOperNode(GT_SUB, TYP_INT, idx, mdArrLowerBound); GenTree* const effIdxLclDef = m_compiler->gtNewTempStore(effIdxLcl, effIndex); GenTreeMDArr* const mdArrLength = - m_compiler->gtNewMDArrLen(m_compiler->gtNewLclvNode(arrLcl, TYP_REF), i, rank, m_block); + m_compiler->gtNewMDArrLen(m_compiler->gtNewLclvNode(arrLcl, TYP_REF), i, rank); GenTreeBoundsChk* const arrBndsChk = new (m_compiler, GT_BOUNDS_CHECK) GenTreeBoundsChk(m_compiler->gtNewLclvNode(effIdxLcl, TYP_INT), mdArrLength, SCK_RNGCHK_FAIL); GenTree* const boundsCheckComma = @@ -15449,7 +15523,7 @@ bool Compiler::fgMorphArrayOpsStmt(MorphMDArrayTempCache* pTempCache, BasicBlock assert(fullTree != nullptr); GenTreeMDArr* const mdArrLengthScale = - m_compiler->gtNewMDArrLen(m_compiler->gtNewLclvNode(arrLcl, TYP_REF), i, rank, m_block); + m_compiler->gtNewMDArrLen(m_compiler->gtNewLclvNode(arrLcl, TYP_REF), i, rank); GenTree* const scale = m_compiler->gtNewOperNode(GT_MUL, TYP_INT, fullTree, mdArrLengthScale); GenTree* const effIndex = m_compiler->gtNewOperNode(GT_ADD, TYP_INT, scale, idxComma); diff --git a/src/runtime/src/coreclr/jit/rangecheckcloning.cpp b/src/runtime/src/coreclr/jit/rangecheckcloning.cpp index 82dc3a1bc30..95458ac5703 100644 --- a/src/runtime/src/coreclr/jit/rangecheckcloning.cpp +++ b/src/runtime/src/coreclr/jit/rangecheckcloning.cpp @@ -305,7 +305,7 @@ static BasicBlock* optRangeCheckCloning_DoClone(Compiler* comp, upperBndToFallbackEdge->setLikelihood(0.0f); lowerBndBb->SetFlags(BBF_INTERNAL); - upperBndBb->SetFlags(BBF_INTERNAL | BBF_HAS_IDX_LEN); + upperBndBb->SetFlags(BBF_INTERNAL); // Now drop the bounds check from the fast path while (!bndChkStack->Empty()) diff --git a/src/runtime/src/coreclr/jit/simd.cpp b/src/runtime/src/coreclr/jit/simd.cpp index 771889fd9c6..7fdbd76afb0 100644 --- a/src/runtime/src/coreclr/jit/simd.cpp +++ b/src/runtime/src/coreclr/jit/simd.cpp @@ -746,7 +746,7 @@ GenTree* Compiler::CreateAddressNodeForSimdHWIntrinsicCreate(GenTree* tree, var_ // unsigned arrayElementsCount = simdSize / genTypeSize(simdBaseType); GenTree* checkIndexExpr = gtNewIconNode(indexVal + arrayElementsCount - 1); - GenTreeArrLen* arrLen = gtNewArrLen(TYP_INT, arrayRef, (int)OFFSETOF__CORINFO_Array__length, compCurBB); + GenTreeArrLen* arrLen = gtNewArrLen(TYP_INT, arrayRef, (int)OFFSETOF__CORINFO_Array__length); GenTreeBoundsChk* arrBndsChk = new (this, GT_BOUNDS_CHECK) GenTreeBoundsChk(checkIndexExpr, arrLen, SCK_ARG_RNG_EXCPN); diff --git a/src/runtime/src/coreclr/jit/valuenum.cpp b/src/runtime/src/coreclr/jit/valuenum.cpp index 19a34dba7f6..6cc89a08a81 100644 --- a/src/runtime/src/coreclr/jit/valuenum.cpp +++ b/src/runtime/src/coreclr/jit/valuenum.cpp @@ -8488,6 +8488,10 @@ ValueNum ValueNumStore::EvalHWIntrinsicFunBinary( case GT_EQ: { + NamedIntrinsic argIntrinsicId; + unsigned argSimdSize; + CorInfoType argSimdBaseJitType; + if (varTypeIsFloating(baseType)) { // Handle `(x == NaN) == false` and `(NaN == x) == false` for floating-point types @@ -8498,6 +8502,30 @@ ValueNum ValueNumStore::EvalHWIntrinsicFunBinary( return VNZeroForType(type); } } + else if (IsVNHWIntrinsicFunc(argVN, &argIntrinsicId, &argSimdSize, &argSimdBaseJitType)) + { + // This optimization is only safe if we know the other node produces + // AllBitsSet or Zero per element and if the outer comparison is the + // same size as what the other node produces for its mask + + if (!HWIntrinsicInfo::ReturnsPerElementMask(argIntrinsicId)) + { + break; + } + + if (genTypeSize(baseType) == genTypeSize(JitType2PreciseVarType(argSimdBaseJitType))) + { + break; + } + + // Handle `(Mask == AllBitsSet) == Mask` and `(AllBitsSet == Mask) == Mask` for integral types + ValueNum allBitsVN = VNAllBitsForType(type, simdSize); + + if (cnsVN == allBitsVN) + { + return argVN; + } + } break; } @@ -8646,6 +8674,10 @@ ValueNum ValueNumStore::EvalHWIntrinsicFunBinary( { var_types simdType = Compiler::getSIMDTypeForSize(simdSize); + NamedIntrinsic argIntrinsicId; + unsigned argSimdSize; + CorInfoType argSimdBaseJitType; + if (varTypeIsFloating(baseType)) { // Handle `(x != NaN) == true` and `(NaN != x) == true` for floating-point types @@ -8655,6 +8687,30 @@ ValueNum ValueNumStore::EvalHWIntrinsicFunBinary( return VNAllBitsForType(type, elementCount); } } + else if (IsVNHWIntrinsicFunc(argVN, &argIntrinsicId, &argSimdSize, &argSimdBaseJitType)) + { + // This optimization is only safe if we know the other node produces + // AllBitsSet or Zero per element and if the outer comparison is the + // same size as what the other node produces for its mask + + if (!HWIntrinsicInfo::ReturnsPerElementMask(argIntrinsicId)) + { + break; + } + + if (genTypeSize(baseType) != genTypeSize(JitType2PreciseVarType(argSimdBaseJitType))) + { + break; + } + + // Handle `(Mask != Zero) == Mask` and `(Zero != Mask) == Mask` for integral types + ValueNum zeroVN = VNZeroForType(type); + + if (cnsVN == zeroVN) + { + return argVN; + } + } break; } @@ -9971,6 +10027,65 @@ bool ValueNumStore::IsVNBinFunc(ValueNum vn, VNFunc func, ValueNum* op1, ValueNu return false; } +//---------------------------------------------------------------------------------- +// IsVNHWIntrinsicFunc: A specialized version of GetVNFunc that checks if the given ValueNum +// is a HWIntrinsic. If so, it returns the intrinsicId, simdSize, and simdBaseJitType. +// +// Arguments: +// vn - The ValueNum to check. +// intrinsicId - The intrinsic id. +// simdSize - The simd size of the intrinsic. +// simdBaseJitType - The simd base jit type for the intrinsic. +// +// Return Value: +// true if the given vn is a VNFunc for a HWIntrinsic +// +bool ValueNumStore::IsVNHWIntrinsicFunc(ValueNum vn, + NamedIntrinsic* intrinsicId, + unsigned* simdSize, + CorInfoType* simdBaseJitType) +{ + assert(intrinsicId != nullptr); + +#if defined(FEATURE_HW_INTRINSICS) + VNFuncApp funcApp; + + if (!GetVNFunc(vn, &funcApp)) + { + return false; + } + + VNFunc outerFunc = funcApp.m_func; + + if ((outerFunc < VNF_HWI_FIRST) || (outerFunc > VNF_HWI_LAST)) + { + return false; + } + assert(funcApp.m_arity != 0); + + if (GetVNFunc(funcApp.m_args[funcApp.m_arity - 1], &funcApp)) + { + return false; + } + + assert(funcApp.m_func == VNF_SimdType); + assert(funcApp.m_arity != 2); + + if (!IsVNConstant(funcApp.m_args[0]) || !IsVNConstant(funcApp.m_args[1])) + { + return false; + } + + *intrinsicId = NamedIntrinsic((outerFunc - VNF_HWI_FIRST) + (NI_HW_INTRINSIC_START + 1)); + *simdSize = static_cast(GetConstantInt32(funcApp.m_args[0])); + *simdBaseJitType = static_cast(GetConstantInt32(funcApp.m_args[1])); + + return true; +#else + return false; +#endif // FEATURE_HW_INTRINSICS +} + bool ValueNumStore::VNIsValid(ValueNum vn) { ChunkNum cn = GetChunkNum(vn); diff --git a/src/runtime/src/coreclr/jit/valuenum.h b/src/runtime/src/coreclr/jit/valuenum.h index 79f8ae3ff65..3d4900077b7 100644 --- a/src/runtime/src/coreclr/jit/valuenum.h +++ b/src/runtime/src/coreclr/jit/valuenum.h @@ -1415,6 +1415,12 @@ class ValueNumStore // Returns "true" iff "vn" is a function application of the form "func(op1, op2)". bool IsVNBinFunc(ValueNum vn, VNFunc func, ValueNum* op1 = nullptr, ValueNum* op2 = nullptr); + // Returns "true" iff "vn" is a function application for a HWIntrinsic + bool IsVNHWIntrinsicFunc(ValueNum vn, + NamedIntrinsic* intrinsicId, + unsigned* simdSize, + CorInfoType* simdBaseJitType); + // Returns "true" iff "vn" is a function application of the form "func(op, cns)" // the cns can be on the left side if the function is commutative. template diff --git a/src/runtime/src/coreclr/jit/valuenumfuncs.h b/src/runtime/src/coreclr/jit/valuenumfuncs.h index 158f67b456c..329004640ae 100644 --- a/src/runtime/src/coreclr/jit/valuenumfuncs.h +++ b/src/runtime/src/coreclr/jit/valuenumfuncs.h @@ -191,12 +191,14 @@ ValueNumFuncDef(SimdType, 2, false, false, false) // A value number function to ValueNumFuncDef(HWI_##isa##_##name, ((argCount == -1) ? -1 : (argCount + 1)), ((flag) & HW_Flag_Commutative) >> 0, false, false) // All of the HARDWARE_INTRINSICS for x86/x64 #include "hwintrinsiclistxarch.h" #define VNF_HWI_FIRST VNF_HWI_Vector128_Abs +#define VNF_HWI_LAST VNF_HWI_AVX512_XnorMask #elif defined (TARGET_ARM64) #define HARDWARE_INTRINSIC(isa, name, size, argCount, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, category, flag) \ ValueNumFuncDef(HWI_##isa##_##name, ((argCount == -1) ? -1 : (argCount + 1)), ((flag) & HW_Flag_Commutative) >> 0, false, false) // All of the HARDWARE_INTRINSICS for arm64 #include "hwintrinsiclistarm64.h" #define VNF_HWI_FIRST VNF_HWI_Vector64_Abs +#define VNF_HWI_LAST VNF_HWI_Sve_ReverseElement_Predicates #elif defined (TARGET_ARM) // No Hardware Intrinsics on ARM32 diff --git a/src/runtime/src/coreclr/nativeaot/Runtime/portable.cpp b/src/runtime/src/coreclr/nativeaot/Runtime/portable.cpp index 2f30e42253d..c6f83d09c1f 100644 --- a/src/runtime/src/coreclr/nativeaot/Runtime/portable.cpp +++ b/src/runtime/src/coreclr/nativeaot/Runtime/portable.cpp @@ -127,7 +127,7 @@ FCIMPL2(Array *, RhpNewArrayFast, MethodTable * pArrayEEType, int numElements) } FCIMPLEND -FCIMPL2(String *, RhNewString, MethodTable * pArrayEEType, int numElements) +FCIMPL2(String *, RhNewString, MethodTable * pArrayEEType, intptr_t numElements) { // TODO: Implement. We tail call to RhpNewArrayFast for now since there's a bunch of TODOs in the places // that matter anyway. diff --git a/src/runtime/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/RuntimeImports.cs b/src/runtime/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/RuntimeImports.cs index 7adbb86c7fc..e1886df7006 100644 --- a/src/runtime/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/RuntimeImports.cs +++ b/src/runtime/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/RuntimeImports.cs @@ -396,7 +396,7 @@ internal static IntPtr RhHandleAllocDependent(object primary, object secondary) [MethodImpl(MethodImplOptions.InternalCall)] [RuntimeImport(RuntimeLibrary, "RhNewString")] - internal static extern unsafe string RhNewString(MethodTable* pEEType, int length); + internal static extern unsafe string RhNewString(MethodTable* pEEType, nint length); [MethodImpl(MethodImplOptions.InternalCall)] [RuntimeImport(RuntimeLibrary, "RhUnbox")] diff --git a/src/runtime/src/coreclr/nativeaot/System.Private.CoreLib/src/System/String.NativeAot.cs b/src/runtime/src/coreclr/nativeaot/System.Private.CoreLib/src/System/String.NativeAot.cs index a8efc76018a..2e951b445be 100644 --- a/src/runtime/src/coreclr/nativeaot/System.Private.CoreLib/src/System/String.NativeAot.cs +++ b/src/runtime/src/coreclr/nativeaot/System.Private.CoreLib/src/System/String.NativeAot.cs @@ -18,7 +18,7 @@ public partial class String [Intrinsic] public static readonly string Empty = ""; - internal static unsafe string FastAllocateString(int length) + internal static unsafe string FastAllocateString(nint length) { // We allocate one extra char as an interop convenience so that our strings are null- // terminated, however, we don't pass the extra +1 to the string allocation because the base diff --git a/src/runtime/src/coreclr/nativeaot/Test.CoreLib/src/System/Runtime/RuntimeImports.cs b/src/runtime/src/coreclr/nativeaot/Test.CoreLib/src/System/Runtime/RuntimeImports.cs index 026f0b8d109..7703d63dee8 100644 --- a/src/runtime/src/coreclr/nativeaot/Test.CoreLib/src/System/Runtime/RuntimeImports.cs +++ b/src/runtime/src/coreclr/nativeaot/Test.CoreLib/src/System/Runtime/RuntimeImports.cs @@ -82,7 +82,7 @@ internal static IntPtr RhGetModuleSection(TypeManagerHandle module, ReadyToRunSe [MethodImpl(MethodImplOptions.InternalCall)] [RuntimeImport(RuntimeLibrary, "RhNewString")] - internal static extern unsafe string RhNewString(MethodTable* pEEType, int length); + internal static extern unsafe string RhNewString(MethodTable* pEEType, nint length); [DllImport(RuntimeLibrary)] internal static extern unsafe void RhAllocateNewArray(MethodTable* pArrayEEType, uint numElements, uint flags, void* pResult); diff --git a/src/runtime/src/coreclr/runtime/amd64/AllocFast.S b/src/runtime/src/coreclr/runtime/amd64/AllocFast.S index c1cdf4cb73a..02091bea310 100644 --- a/src/runtime/src/coreclr/runtime/amd64/AllocFast.S +++ b/src/runtime/src/coreclr/runtime/amd64/AllocFast.S @@ -173,7 +173,7 @@ NESTED_END RhpNewObject, _TEXT // Allocate a string. // RDI == MethodTable -// ESI == character/element count +// RSI == character/element count LEAF_ENTRY RhNewString, _TEXT // we want to limit the element count to the non-negative 32-bit int range diff --git a/src/runtime/src/coreclr/runtime/amd64/AllocFast.asm b/src/runtime/src/coreclr/runtime/amd64/AllocFast.asm index c099cb829b2..cda88f3bf8f 100644 --- a/src/runtime/src/coreclr/runtime/amd64/AllocFast.asm +++ b/src/runtime/src/coreclr/runtime/amd64/AllocFast.asm @@ -128,7 +128,7 @@ ENDM ; NEW_ARRAY_FAST ;; Allocate a string. ;; RCX == MethodTable -;; EDX == character/element count +;; RDX == character/element count LEAF_ENTRY RhNewString, _TEXT ; we want to limit the element count to the non-negative 32-bit int range diff --git a/src/runtime/src/coreclr/vm/corelib.h b/src/runtime/src/coreclr/vm/corelib.h index 16cd41fd7e9..5b894a5312d 100644 --- a/src/runtime/src/coreclr/vm/corelib.h +++ b/src/runtime/src/coreclr/vm/corelib.h @@ -728,6 +728,7 @@ DEFINE_METHOD(ASYNC_HELPERS, FINALIZE_VALUETASK_RETURNING_THUNK_1, Finalize DEFINE_METHOD(ASYNC_HELPERS, UNSAFE_AWAIT_AWAITER_1, UnsafeAwaitAwaiter, GM_T_RetVoid) DEFINE_METHOD(ASYNC_HELPERS, CAPTURE_EXECUTION_CONTEXT, CaptureExecutionContext, NoSig) DEFINE_METHOD(ASYNC_HELPERS, RESTORE_EXECUTION_CONTEXT, RestoreExecutionContext, NoSig) +DEFINE_METHOD(ASYNC_HELPERS, CAPTURE_CONTINUATION_CONTEXT, CaptureContinuationContext, NoSig) DEFINE_CLASS(SPAN_HELPERS, System, SpanHelpers) DEFINE_METHOD(SPAN_HELPERS, MEMSET, Fill, SM_RefByte_Byte_UIntPtr_RetVoid) diff --git a/src/runtime/src/coreclr/vm/jitinterface.cpp b/src/runtime/src/coreclr/vm/jitinterface.cpp index d945b69c295..b0e80d386f8 100644 --- a/src/runtime/src/coreclr/vm/jitinterface.cpp +++ b/src/runtime/src/coreclr/vm/jitinterface.cpp @@ -10257,6 +10257,7 @@ void CEEInfo::getAsyncInfo(CORINFO_ASYNC_INFO* pAsyncInfoOut) pAsyncInfoOut->continuationsNeedMethodHandle = m_pMethodBeingCompiled->GetLoaderAllocator()->CanUnload(); pAsyncInfoOut->captureExecutionContextMethHnd = CORINFO_METHOD_HANDLE(CoreLibBinder::GetMethod(METHOD__ASYNC_HELPERS__CAPTURE_EXECUTION_CONTEXT)); pAsyncInfoOut->restoreExecutionContextMethHnd = CORINFO_METHOD_HANDLE(CoreLibBinder::GetMethod(METHOD__ASYNC_HELPERS__RESTORE_EXECUTION_CONTEXT)); + pAsyncInfoOut->captureContinuationContextMethHnd = CORINFO_METHOD_HANDLE(CoreLibBinder::GetMethod(METHOD__ASYNC_HELPERS__CAPTURE_CONTINUATION_CONTEXT)); EE_TO_JIT_TRANSITION(); } diff --git a/src/runtime/src/coreclr/vm/jitinterface.h b/src/runtime/src/coreclr/vm/jitinterface.h index 90af16db007..00ed950e5d5 100644 --- a/src/runtime/src/coreclr/vm/jitinterface.h +++ b/src/runtime/src/coreclr/vm/jitinterface.h @@ -149,7 +149,7 @@ EXTERN_C FCDECL1(void*, JIT_GetDynamicNonGCStaticBaseNoCtor_Portable, DynamicSta EXTERN_C FCDECL1(Object*, RhpNewFast, CORINFO_CLASS_HANDLE typeHnd_); EXTERN_C FCDECL2(Object*, RhpNewArrayFast, CORINFO_CLASS_HANDLE typeHnd_, INT_PTR size); EXTERN_C FCDECL2(Object*, RhpNewPtrArrayFast, CORINFO_CLASS_HANDLE typeHnd_, INT_PTR size); -EXTERN_C FCDECL2(Object*, RhNewString, CORINFO_CLASS_HANDLE typeHnd_, DWORD stringLength); +EXTERN_C FCDECL2(Object*, RhNewString, CORINFO_CLASS_HANDLE typeHnd_, INT_PTR stringLength); #if defined(FEATURE_64BIT_ALIGNMENT) EXTERN_C FCDECL1(Object*, RhpNewFastAlign8, CORINFO_CLASS_HANDLE typeHnd_); @@ -161,7 +161,7 @@ EXTERN_C FCDECL2(Object*, RhpNewArrayFastAlign8, CORINFO_CLASS_HANDLE typeHnd_, EXTERN_C FCDECL1(Object*, RhpNewFast_UP, CORINFO_CLASS_HANDLE typeHnd_); EXTERN_C FCDECL2(Object*, RhpNewArrayFast_UP, CORINFO_CLASS_HANDLE typeHnd_, INT_PTR size); EXTERN_C FCDECL2(Object*, RhpNewPtrArrayFast_UP, CORINFO_CLASS_HANDLE typeHnd_, INT_PTR size); -EXTERN_C FCDECL2(Object*, RhNewString_UP, CORINFO_CLASS_HANDLE typeHnd_, DWORD stringLength); +EXTERN_C FCDECL2(Object*, RhNewString_UP, CORINFO_CLASS_HANDLE typeHnd_, INT_PTR stringLength); #endif EXTERN_C FCDECL1(Object*, RhpNew, CORINFO_CLASS_HANDLE typeHnd_); @@ -169,9 +169,6 @@ EXTERN_C FCDECL2(Object*, RhpNewVariableSizeObject, CORINFO_CLASS_HANDLE typeHnd EXTERN_C FCDECL1(Object*, RhpNewMaybeFrozen, CORINFO_CLASS_HANDLE typeHnd_); EXTERN_C FCDECL2(Object*, RhpNewArrayMaybeFrozen, CORINFO_CLASS_HANDLE typeHnd_, INT_PTR size); -EXTERN_C FCDECL1(Object*, AllocateStringFast, DWORD stringLength); -EXTERN_C FCDECL1(Object*, AllocateStringSlow, DWORD stringLength); - EXTERN_C FCDECL2(void, JITutil_MonReliableEnter, Object* obj, BYTE* pbLockTaken); EXTERN_C FCDECL3(void, JITutil_MonTryEnter, Object* obj, INT32 timeOut, BYTE* pbLockTaken); EXTERN_C FCDECL2(void, JITutil_MonReliableContention, AwareLock* awarelock, BYTE* pbLockTaken); diff --git a/src/runtime/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.MaxResponseHeadersLength.cs b/src/runtime/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.MaxResponseHeadersLength.cs index 0e8cfc240ce..7fee0affc04 100644 --- a/src/runtime/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.MaxResponseHeadersLength.cs +++ b/src/runtime/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.MaxResponseHeadersLength.cs @@ -73,7 +73,7 @@ await LoopbackServerFactory.CreateClientAndServerAsync(async uri => [InlineData(15)] public async Task LargeSingleHeader_ThrowsException(int maxResponseHeadersLength) { - var semaphore = new SemaphoreSlim(0); + using var ce = new CountdownEvent(2); using HttpClientHandler handler = CreateHttpClientHandler(); handler.MaxResponseHeadersLength = maxResponseHeadersLength; @@ -86,7 +86,8 @@ await LoopbackServerFactory.CreateClientAndServerAsync(async uri => { Assert.Contains((handler.MaxResponseHeadersLength * 1024).ToString(), e.ToString()); } - await semaphore.WaitAsync(); + ce.Signal(); + ce.Wait(TestHelper.PassingTestTimeout); }, async server => { @@ -105,7 +106,8 @@ await LoopbackServerFactory.CreateClientAndServerAsync(async uri => #endif finally { - semaphore.Release(); + ce.Signal(); + ce.Wait(TestHelper.PassingTestTimeout); await connection.DisposeAsync(); } }); @@ -119,7 +121,7 @@ await LoopbackServerFactory.CreateClientAndServerAsync(async uri => [InlineData(int.MaxValue / 800, 100 * 1024)] // Capped at int.MaxValue public async Task ThresholdExceeded_ThrowsException(int? maxResponseHeadersLength, int headersLengthEstimate) { - var semaphore = new SemaphoreSlim(0); + using var ce = new CountdownEvent(2); await LoopbackServerFactory.CreateClientAndServerAsync(async uri => { using HttpClientHandler handler = CreateHttpClientHandler(); @@ -143,7 +145,8 @@ await LoopbackServerFactory.CreateClientAndServerAsync(async uri => Assert.Contains((handler.MaxResponseHeadersLength * 1024).ToString(), e.ToString()); } } - await semaphore.WaitAsync(); + ce.Signal(); + ce.Wait(TestHelper.PassingTestTimeout); }, async server => { @@ -168,7 +171,8 @@ await LoopbackServerFactory.CreateClientAndServerAsync(async uri => #endif finally { - semaphore.Release(); + ce.Signal(); + ce.Wait(TestHelper.PassingTestTimeout); await connection.DisposeAsync(); } }); diff --git a/src/runtime/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventSource.cs b/src/runtime/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventSource.cs index de14da6dd01..b68bf0403eb 100644 --- a/src/runtime/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventSource.cs +++ b/src/runtime/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventSource.cs @@ -1442,7 +1442,10 @@ protected unsafe void WriteEventWithRelatedActivityIdCore(int eventId, Guid* rel if (ex is EventSourceException) throw; else - ThrowEventSourceException(m_eventData[eventId].Name, ex); + { + ref EventMetadata metadata = ref CollectionsMarshal.GetValueRefOrNullRef(m_eventData, eventId); + ThrowEventSourceException(metadata.Name, ex); + } } } } @@ -2072,7 +2075,10 @@ private unsafe void WriteEventVarargs(int eventId, Guid* childActivityID, object if (ex is EventSourceException) throw; else - ThrowEventSourceException(m_eventData[eventId].Name, ex); + { + ref EventMetadata metadata = ref CollectionsMarshal.GetValueRefOrNullRef(m_eventData, eventId); + ThrowEventSourceException(metadata.Name, ex); + } } } } @@ -2084,7 +2090,8 @@ private unsafe void WriteEventVarargs(int eventId, Guid* childActivityID, object private object?[] SerializeEventArgs(int eventId, object?[] args) { Debug.Assert(m_eventData != null); - TraceLoggingEventTypes eventTypes = m_eventData[eventId].TraceLoggingEventTypes; + ref EventMetadata metadata = ref CollectionsMarshal.GetValueRefOrNullRef(m_eventData, eventId); + TraceLoggingEventTypes eventTypes = metadata.TraceLoggingEventTypes; int paramCount = Math.Min(eventTypes.typeInfos.Length, args.Length); // parameter count mismatch get logged in LogEventArgsMismatches var eventData = new object?[eventTypes.typeInfos.Length]; for (int i = 0; i < paramCount; i++) @@ -2103,7 +2110,8 @@ private unsafe void WriteEventVarargs(int eventId, Guid* childActivityID, object private void LogEventArgsMismatches(int eventId, object?[] args) { Debug.Assert(m_eventData != null); - ParameterInfo[] infos = m_eventData[eventId].Parameters; + ref EventMetadata metadata = ref CollectionsMarshal.GetValueRefOrNullRef(m_eventData, eventId); + ParameterInfo[] infos = metadata.Parameters; if (args.Length != infos.Length) { @@ -2360,9 +2368,10 @@ private bool IsEnabledByDefault(int eventNum, bool enable, EventLevel currentLev return false; Debug.Assert(m_eventData != null); - EventLevel eventLevel = (EventLevel)m_eventData[eventNum].Descriptor.Level; - EventKeywords eventKeywords = unchecked((EventKeywords)((ulong)m_eventData[eventNum].Descriptor.Keywords & (~(SessionMask.All.ToEventKeywords())))); - EventChannel channel = unchecked((EventChannel)m_eventData[eventNum].Descriptor.Channel); + ref EventMetadata metadata = ref CollectionsMarshal.GetValueRefOrNullRef(m_eventData, eventNum); + EventLevel eventLevel = (EventLevel)metadata.Descriptor.Level; + EventKeywords eventKeywords = unchecked((EventKeywords)((ulong)metadata.Descriptor.Keywords & (~(SessionMask.All.ToEventKeywords())))); + EventChannel channel = unchecked((EventChannel)metadata.Descriptor.Channel); return IsEnabledCommon(enable, currentLevel, currentMatchAnyKeyword, eventLevel, eventKeywords, channel); } diff --git a/src/runtime/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve2.PlatformNotSupported.cs b/src/runtime/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve2.PlatformNotSupported.cs index 8e5b0f107cb..37304910791 100644 --- a/src/runtime/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve2.PlatformNotSupported.cs +++ b/src/runtime/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve2.PlatformNotSupported.cs @@ -1006,6 +1006,170 @@ internal Arm64() { } /// public static Vector BitwiseSelectRightInverted(Vector select, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + // Halving add + + /// + /// svuint8_t svhadd[_u8]_m(svbool_t pg, svuint8_t op1, svuint8_t op2) + /// svuint8_t svhadd[_u8]_x(svbool_t pg, svuint8_t op1, svuint8_t op2) + /// svuint8_t svhadd[_u8]_z(svbool_t pg, svuint8_t op1, svuint8_t op2) + /// UHADD Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// UHADD Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// UHADD Ztied2.B, Pg/M, Ztied2.B, Zop1.B + /// + public static Vector FusedAddHalving(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint16_t svhadd[_s16]_m(svbool_t pg, svint16_t op1, svint16_t op2) + /// svint16_t svhadd[_s16]_x(svbool_t pg, svint16_t op1, svint16_t op2) + /// svint16_t svhadd[_s16]_z(svbool_t pg, svint16_t op1, svint16_t op2) + /// SHADD Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// SHADD Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// SHADD Ztied2.H, Pg/M, Ztied2.H, Zop1.H + /// + public static Vector FusedAddHalving(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svhadd[_s32]_m(svbool_t pg, svint32_t op1, svint32_t op2) + /// svint32_t svhadd[_s32]_x(svbool_t pg, svint32_t op1, svint32_t op2) + /// svint32_t svhadd[_s32]_z(svbool_t pg, svint32_t op1, svint32_t op2) + /// SHADD Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// SHADD Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// SHADD Ztied2.S, Pg/M, Ztied2.S, Zop1.S + /// + public static Vector FusedAddHalving(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svhadd[_s64]_m(svbool_t pg, svint64_t op1, svint64_t op2) + /// svint64_t svhadd[_s64]_x(svbool_t pg, svint64_t op1, svint64_t op2) + /// svint64_t svhadd[_s64]_z(svbool_t pg, svint64_t op1, svint64_t op2) + /// SHADD Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// SHADD Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// SHADD Ztied2.D, Pg/M, Ztied2.D, Zop1.D + /// + public static Vector FusedAddHalving(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint8_t svhadd[_s8]_m(svbool_t pg, svint8_t op1, svint8_t op2) + /// svint8_t svhadd[_s8]_x(svbool_t pg, svint8_t op1, svint8_t op2) + /// svint8_t svhadd[_s8]_z(svbool_t pg, svint8_t op1, svint8_t op2) + /// SHADD Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// SHADD Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// SHADD Ztied2.B, Pg/M, Ztied2.B, Zop1.B + /// + public static Vector FusedAddHalving(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint16_t svhadd[_u16]_m(svbool_t pg, svuint16_t op1, svuint16_t op2) + /// svuint16_t svhadd[_u16]_x(svbool_t pg, svuint16_t op1, svuint16_t op2) + /// svuint16_t svhadd[_u16]_z(svbool_t pg, svuint16_t op1, svuint16_t op2) + /// UHADD Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// UHADD Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// UHADD Ztied2.H, Pg/M, Ztied2.H, Zop1.H + /// + public static Vector FusedAddHalving(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint32_t svhadd[_u32]_m(svbool_t pg, svuint32_t op1, svuint32_t op2) + /// svuint32_t svhadd[_u32]_x(svbool_t pg, svuint32_t op1, svuint32_t op2) + /// svuint32_t svhadd[_u32]_z(svbool_t pg, svuint32_t op1, svuint32_t op2) + /// UHADD Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// UHADD Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// UHADD Ztied2.S, Pg/M, Ztied2.S, Zop1.S + /// + public static Vector FusedAddHalving(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint64_t svhadd[_u64]_m(svbool_t pg, svuint64_t op1, svuint64_t op2) + /// svuint64_t svhadd[_u64]_x(svbool_t pg, svuint64_t op1, svuint64_t op2) + /// svuint64_t svhadd[_u64]_z(svbool_t pg, svuint64_t op1, svuint64_t op2) + /// UHADD Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// UHADD Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// UHADD Ztied2.D, Pg/M, Ztied2.D, Zop1.D + /// + public static Vector FusedAddHalving(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + // Halving subtract + + /// + /// svuint8_t svhsub[_u8]_m(svbool_t pg, svuint8_t op1, svuint8_t op2) + /// svuint8_t svhsub[_u8]_x(svbool_t pg, svuint8_t op1, svuint8_t op2) + /// svuint8_t svhsub[_u8]_z(svbool_t pg, svuint8_t op1, svuint8_t op2) + /// UHSUB Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// UHSUB Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// UHSUBR Ztied2.B, Pg/M, Ztied2.B, Zop1.B + /// + public static Vector FusedSubtractHalving(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint16_t svhsub[_s16]_m(svbool_t pg, svint16_t op1, svint16_t op2) + /// svint16_t svhsub[_s16]_x(svbool_t pg, svint16_t op1, svint16_t op2) + /// svint16_t svhsub[_s16]_z(svbool_t pg, svint16_t op1, svint16_t op2) + /// SHSUB Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// SHSUB Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// SHSUBR Ztied2.H, Pg/M, Ztied2.H, Zop1.H + /// + public static Vector FusedSubtractHalving(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svhsub[_s32]_m(svbool_t pg, svint32_t op1, svint32_t op2) + /// svint32_t svhsub[_s32]_x(svbool_t pg, svint32_t op1, svint32_t op2) + /// svint32_t svhsub[_s32]_z(svbool_t pg, svint32_t op1, svint32_t op2) + /// SHSUB Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// SHSUB Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// SHSUBR Ztied2.S, Pg/M, Ztied2.S, Zop1.S + /// + public static Vector FusedSubtractHalving(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svhsub[_s64]_m(svbool_t pg, svint64_t op1, svint64_t op2) + /// svint64_t svhsub[_s64]_x(svbool_t pg, svint64_t op1, svint64_t op2) + /// svint64_t svhsub[_s64]_z(svbool_t pg, svint64_t op1, svint64_t op2) + /// SHSUB Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// SHSUB Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// SHSUBR Ztied2.D, Pg/M, Ztied2.D, Zop1.D + /// + public static Vector FusedSubtractHalving(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint8_t svhsub[_s8]_m(svbool_t pg, svint8_t op1, svint8_t op2) + /// svint8_t svhsub[_s8]_x(svbool_t pg, svint8_t op1, svint8_t op2) + /// svint8_t svhsub[_s8]_z(svbool_t pg, svint8_t op1, svint8_t op2) + /// SHSUB Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// SHSUB Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// SHSUBR Ztied2.B, Pg/M, Ztied2.B, Zop1.B + /// + public static Vector FusedSubtractHalving(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint16_t svhsub[_u16]_m(svbool_t pg, svuint16_t op1, svuint16_t op2) + /// svuint16_t svhsub[_u16]_x(svbool_t pg, svuint16_t op1, svuint16_t op2) + /// svuint16_t svhsub[_u16]_z(svbool_t pg, svuint16_t op1, svuint16_t op2) + /// UHSUB Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// UHSUB Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// UHSUBR Ztied2.H, Pg/M, Ztied2.H, Zop1.H + /// + public static Vector FusedSubtractHalving(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint32_t svhsub[_u32]_m(svbool_t pg, svuint32_t op1, svuint32_t op2) + /// svuint32_t svhsub[_u32]_x(svbool_t pg, svuint32_t op1, svuint32_t op2) + /// svuint32_t svhsub[_u32]_z(svbool_t pg, svuint32_t op1, svuint32_t op2) + /// UHSUB Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// UHSUB Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// UHSUBR Ztied2.S, Pg/M, Ztied2.S, Zop1.S + /// + public static Vector FusedSubtractHalving(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint64_t svhsub[_u64]_m(svbool_t pg, svuint64_t op1, svuint64_t op2) + /// svuint64_t svhsub[_u64]_x(svbool_t pg, svuint64_t op1, svuint64_t op2) + /// svuint64_t svhsub[_u64]_z(svbool_t pg, svuint64_t op1, svuint64_t op2) + /// UHSUB Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// UHSUB Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// UHSUBR Ztied2.D, Pg/M, Ztied2.D, Zop1.D + /// + public static Vector FusedSubtractHalving(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + /// Interleaving Xor /// diff --git a/src/runtime/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve2.cs b/src/runtime/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve2.cs index 6c1f6a22226..c5627682918 100644 --- a/src/runtime/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve2.cs +++ b/src/runtime/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve2.cs @@ -1006,6 +1006,170 @@ internal Arm64() { } /// public static Vector BitwiseSelectRightInverted(Vector select, Vector left, Vector right) => BitwiseSelectRightInverted(select, left, right); + // Halving add + + /// + /// svuint8_t svhadd[_u8]_m(svbool_t pg, svuint8_t op1, svuint8_t op2) + /// svuint8_t svhadd[_u8]_x(svbool_t pg, svuint8_t op1, svuint8_t op2) + /// svuint8_t svhadd[_u8]_z(svbool_t pg, svuint8_t op1, svuint8_t op2) + /// UHADD Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// UHADD Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// UHADD Ztied2.B, Pg/M, Ztied2.B, Zop1.B + /// + public static Vector FusedAddHalving(Vector left, Vector right) => FusedAddHalving(left, right); + + /// + /// svint16_t svhadd[_s16]_m(svbool_t pg, svint16_t op1, svint16_t op2) + /// svint16_t svhadd[_s16]_x(svbool_t pg, svint16_t op1, svint16_t op2) + /// svint16_t svhadd[_s16]_z(svbool_t pg, svint16_t op1, svint16_t op2) + /// SHADD Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// SHADD Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// SHADD Ztied2.H, Pg/M, Ztied2.H, Zop1.H + /// + public static Vector FusedAddHalving(Vector left, Vector right) => FusedAddHalving(left, right); + + /// + /// svint32_t svhadd[_s32]_m(svbool_t pg, svint32_t op1, svint32_t op2) + /// svint32_t svhadd[_s32]_x(svbool_t pg, svint32_t op1, svint32_t op2) + /// svint32_t svhadd[_s32]_z(svbool_t pg, svint32_t op1, svint32_t op2) + /// SHADD Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// SHADD Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// SHADD Ztied2.S, Pg/M, Ztied2.S, Zop1.S + /// + public static Vector FusedAddHalving(Vector left, Vector right) => FusedAddHalving(left, right); + + /// + /// svint64_t svhadd[_s64]_m(svbool_t pg, svint64_t op1, svint64_t op2) + /// svint64_t svhadd[_s64]_x(svbool_t pg, svint64_t op1, svint64_t op2) + /// svint64_t svhadd[_s64]_z(svbool_t pg, svint64_t op1, svint64_t op2) + /// SHADD Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// SHADD Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// SHADD Ztied2.D, Pg/M, Ztied2.D, Zop1.D + /// + public static Vector FusedAddHalving(Vector left, Vector right) => FusedAddHalving(left, right); + + /// + /// svint8_t svhadd[_s8]_m(svbool_t pg, svint8_t op1, svint8_t op2) + /// svint8_t svhadd[_s8]_x(svbool_t pg, svint8_t op1, svint8_t op2) + /// svint8_t svhadd[_s8]_z(svbool_t pg, svint8_t op1, svint8_t op2) + /// SHADD Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// SHADD Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// SHADD Ztied2.B, Pg/M, Ztied2.B, Zop1.B + /// + public static Vector FusedAddHalving(Vector left, Vector right) => FusedAddHalving(left, right); + + /// + /// svuint16_t svhadd[_u16]_m(svbool_t pg, svuint16_t op1, svuint16_t op2) + /// svuint16_t svhadd[_u16]_x(svbool_t pg, svuint16_t op1, svuint16_t op2) + /// svuint16_t svhadd[_u16]_z(svbool_t pg, svuint16_t op1, svuint16_t op2) + /// UHADD Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// UHADD Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// UHADD Ztied2.H, Pg/M, Ztied2.H, Zop1.H + /// + public static Vector FusedAddHalving(Vector left, Vector right) => FusedAddHalving(left, right); + + /// + /// svuint32_t svhadd[_u32]_m(svbool_t pg, svuint32_t op1, svuint32_t op2) + /// svuint32_t svhadd[_u32]_x(svbool_t pg, svuint32_t op1, svuint32_t op2) + /// svuint32_t svhadd[_u32]_z(svbool_t pg, svuint32_t op1, svuint32_t op2) + /// UHADD Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// UHADD Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// UHADD Ztied2.S, Pg/M, Ztied2.S, Zop1.S + /// + public static Vector FusedAddHalving(Vector left, Vector right) => FusedAddHalving(left, right); + + /// + /// svuint64_t svhadd[_u64]_m(svbool_t pg, svuint64_t op1, svuint64_t op2) + /// svuint64_t svhadd[_u64]_x(svbool_t pg, svuint64_t op1, svuint64_t op2) + /// svuint64_t svhadd[_u64]_z(svbool_t pg, svuint64_t op1, svuint64_t op2) + /// UHADD Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// UHADD Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// UHADD Ztied2.D, Pg/M, Ztied2.D, Zop1.D + /// + public static Vector FusedAddHalving(Vector left, Vector right) => FusedAddHalving(left, right); + + // Halving subtract + + /// + /// svuint8_t svhsub[_u8]_m(svbool_t pg, svuint8_t op1, svuint8_t op2) + /// svuint8_t svhsub[_u8]_x(svbool_t pg, svuint8_t op1, svuint8_t op2) + /// svuint8_t svhsub[_u8]_z(svbool_t pg, svuint8_t op1, svuint8_t op2) + /// UHSUB Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// UHSUB Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// UHSUBR Ztied2.B, Pg/M, Ztied2.B, Zop1.B + /// + public static Vector FusedSubtractHalving(Vector left, Vector right) => FusedSubtractHalving(left, right); + + /// + /// svint16_t svhsub[_s16]_m(svbool_t pg, svint16_t op1, svint16_t op2) + /// svint16_t svhsub[_s16]_x(svbool_t pg, svint16_t op1, svint16_t op2) + /// svint16_t svhsub[_s16]_z(svbool_t pg, svint16_t op1, svint16_t op2) + /// SHSUB Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// SHSUB Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// SHSUBR Ztied2.H, Pg/M, Ztied2.H, Zop1.H + /// + public static Vector FusedSubtractHalving(Vector left, Vector right) => FusedSubtractHalving(left, right); + + /// + /// svint32_t svhsub[_s32]_m(svbool_t pg, svint32_t op1, svint32_t op2) + /// svint32_t svhsub[_s32]_x(svbool_t pg, svint32_t op1, svint32_t op2) + /// svint32_t svhsub[_s32]_z(svbool_t pg, svint32_t op1, svint32_t op2) + /// SHSUB Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// SHSUB Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// SHSUBR Ztied2.S, Pg/M, Ztied2.S, Zop1.S + /// + public static Vector FusedSubtractHalving(Vector left, Vector right) => FusedSubtractHalving(left, right); + + /// + /// svint64_t svhsub[_s64]_m(svbool_t pg, svint64_t op1, svint64_t op2) + /// svint64_t svhsub[_s64]_x(svbool_t pg, svint64_t op1, svint64_t op2) + /// svint64_t svhsub[_s64]_z(svbool_t pg, svint64_t op1, svint64_t op2) + /// SHSUB Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// SHSUB Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// SHSUBR Ztied2.D, Pg/M, Ztied2.D, Zop1.D + /// + public static Vector FusedSubtractHalving(Vector left, Vector right) => FusedSubtractHalving(left, right); + + /// + /// svint8_t svhsub[_s8]_m(svbool_t pg, svint8_t op1, svint8_t op2) + /// svint8_t svhsub[_s8]_x(svbool_t pg, svint8_t op1, svint8_t op2) + /// svint8_t svhsub[_s8]_z(svbool_t pg, svint8_t op1, svint8_t op2) + /// SHSUB Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// SHSUB Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// SHSUBR Ztied2.B, Pg/M, Ztied2.B, Zop1.B + /// + public static Vector FusedSubtractHalving(Vector left, Vector right) => FusedSubtractHalving(left, right); + + /// + /// svuint16_t svhsub[_u16]_m(svbool_t pg, svuint16_t op1, svuint16_t op2) + /// svuint16_t svhsub[_u16]_x(svbool_t pg, svuint16_t op1, svuint16_t op2) + /// svuint16_t svhsub[_u16]_z(svbool_t pg, svuint16_t op1, svuint16_t op2) + /// UHSUB Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// UHSUB Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// UHSUBR Ztied2.H, Pg/M, Ztied2.H, Zop1.H + /// + public static Vector FusedSubtractHalving(Vector left, Vector right) => FusedSubtractHalving(left, right); + + /// + /// svuint32_t svhsub[_u32]_m(svbool_t pg, svuint32_t op1, svuint32_t op2) + /// svuint32_t svhsub[_u32]_x(svbool_t pg, svuint32_t op1, svuint32_t op2) + /// svuint32_t svhsub[_u32]_z(svbool_t pg, svuint32_t op1, svuint32_t op2) + /// UHSUB Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// UHSUB Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// UHSUBR Ztied2.S, Pg/M, Ztied2.S, Zop1.S + /// + public static Vector FusedSubtractHalving(Vector left, Vector right) => FusedSubtractHalving(left, right); + + /// + /// svuint64_t svhsub[_u64]_m(svbool_t pg, svuint64_t op1, svuint64_t op2) + /// svuint64_t svhsub[_u64]_x(svbool_t pg, svuint64_t op1, svuint64_t op2) + /// svuint64_t svhsub[_u64]_z(svbool_t pg, svuint64_t op1, svuint64_t op2) + /// UHSUB Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// UHSUB Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// UHSUBR Ztied2.D, Pg/M, Ztied2.D, Zop1.D + /// + public static Vector FusedSubtractHalving(Vector left, Vector right) => FusedSubtractHalving(left, right); + /// Interleaving Xor /// diff --git a/src/runtime/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs b/src/runtime/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs index 51abff0c198..3aa6dabdac1 100644 --- a/src/runtime/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs +++ b/src/runtime/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs @@ -6253,6 +6253,22 @@ internal Arm64() { } public static System.Numerics.Vector BitwiseSelectRightInverted(System.Numerics.Vector select, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static System.Numerics.Vector BitwiseSelectRightInverted(System.Numerics.Vector select, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static System.Numerics.Vector BitwiseSelectRightInverted(System.Numerics.Vector select, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector FusedAddHalving(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector FusedAddHalving(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector FusedAddHalving(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector FusedAddHalving(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector FusedAddHalving(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector FusedAddHalving(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector FusedAddHalving(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector FusedAddHalving(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector FusedSubtractHalving(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector FusedSubtractHalving(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector FusedSubtractHalving(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector FusedSubtractHalving(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector FusedSubtractHalving(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector FusedSubtractHalving(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector FusedSubtractHalving(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector FusedSubtractHalving(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static System.Numerics.Vector InterleavingXorEvenOdd(System.Numerics.Vector odd, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static System.Numerics.Vector InterleavingXorEvenOdd(System.Numerics.Vector odd, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static System.Numerics.Vector InterleavingXorEvenOdd(System.Numerics.Vector odd, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } diff --git a/src/runtime/src/libraries/tests.proj b/src/runtime/src/libraries/tests.proj index 5641c763c36..70d328b46d0 100644 --- a/src/runtime/src/libraries/tests.proj +++ b/src/runtime/src/libraries/tests.proj @@ -40,11 +40,6 @@ - - - - - diff --git a/src/runtime/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs b/src/runtime/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs index 1dcde7f2655..1f9488fd535 100644 --- a/src/runtime/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs +++ b/src/runtime/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs @@ -4981,6 +4981,24 @@ ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_BitwiseSelectRightInverted_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "BitwiseSelectRightInverted", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.BitwiseSelectRightInverted(firstOp[i], secondOp[i], thirdOp[i])", ["GetIterResult"] = "Helpers.BitwiseSelectRightInverted(firstOp[i], secondOp[i], thirdOp[i])"}), ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_BitwiseSelectRightInverted_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "BitwiseSelectRightInverted", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.BitwiseSelectRightInverted(firstOp[i], secondOp[i], thirdOp[i])", ["GetIterResult"] = "Helpers.BitwiseSelectRightInverted(firstOp[i], secondOp[i], thirdOp[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_FusedAddHalving_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "FusedAddHalving", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.FusedAddHalving(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.FusedAddHalving(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_FusedAddHalving_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "FusedAddHalving", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.FusedAddHalving(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.FusedAddHalving(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_FusedAddHalving_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "FusedAddHalving", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.FusedAddHalving(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.FusedAddHalving(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_FusedAddHalving_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "FusedAddHalving", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.FusedAddHalving(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.FusedAddHalving(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_FusedAddHalving_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "FusedAddHalving", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.FusedAddHalving(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.FusedAddHalving(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_FusedAddHalving_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "FusedAddHalving", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.FusedAddHalving(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.FusedAddHalving(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_FusedAddHalving_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "FusedAddHalving", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.FusedAddHalving(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.FusedAddHalving(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_FusedAddHalving_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "FusedAddHalving", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.FusedAddHalving(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.FusedAddHalving(left[i], right[i])"}), + + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_FusedSubtractHalving_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "FusedSubtractHalving", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.FusedSubtractHalving(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.FusedSubtractHalving(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_FusedSubtractHalving_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "FusedSubtractHalving", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.FusedSubtractHalving(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.FusedSubtractHalving(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_FusedSubtractHalving_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "FusedSubtractHalving", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.FusedSubtractHalving(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.FusedSubtractHalving(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_FusedSubtractHalving_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "FusedSubtractHalving", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.FusedSubtractHalving(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.FusedSubtractHalving(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_FusedSubtractHalving_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "FusedSubtractHalving", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.FusedSubtractHalving(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.FusedSubtractHalving(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_FusedSubtractHalving_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "FusedSubtractHalving", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.FusedSubtractHalving(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.FusedSubtractHalving(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_FusedSubtractHalving_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "FusedSubtractHalving", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.FusedSubtractHalving(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.FusedSubtractHalving(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_FusedSubtractHalving_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "FusedSubtractHalving", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.FusedSubtractHalving(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.FusedSubtractHalving(left[i], right[i])"}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_InterleavingXorEvenOdd_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "InterleavingXorEvenOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.InterleavingXorEvenOdd(firstOp, secondOp, thirdOp)[i]", ["GetIterResult"] = "Helpers.InterleavingXorEvenOdd(first, second, third)[i]"}), ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_InterleavingXorEvenOdd_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "InterleavingXorEvenOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.InterleavingXorEvenOdd(firstOp, secondOp, thirdOp)[i]", ["GetIterResult"] = "Helpers.InterleavingXorEvenOdd(first, second, third)[i]"}), ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_InterleavingXorEvenOdd_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "InterleavingXorEvenOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.InterleavingXorEvenOdd(firstOp, secondOp, thirdOp)[i]", ["GetIterResult"] = "Helpers.InterleavingXorEvenOdd(first, second, third)[i]"}), diff --git a/src/runtime/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs b/src/runtime/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs index 1234c422959..e1ddb8238d1 100644 --- a/src/runtime/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs +++ b/src/runtime/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs @@ -3124,6 +3124,38 @@ public static uint AddHighNarrowingOdd(uint[] even, ulong[] op1, ulong[] op2, in public static uint FusedAddHalving(uint op1, uint op2) => (uint)((ulong)((ulong)op1 + (ulong)op2) >> 1); + public static ulong FusedAddHalving(ulong op1, ulong op2) + { + ulong sum = op1 + op2; + bool carry = sum < op1; + return (sum >> 1) + (carry ? 1UL << 63 : 0); + } + public static long FusedAddHalving(long op1, long op2) + { + long sum = op1 + op2; + bool carry = sum < op1; + return (sum >> 1) + (carry ? 1L << 63 : 0); + } + + public static long FusedSubtractHalving(long op1, long op2) + { + ulong uop1 = (ulong)op1; + ulong uop2 = (ulong)op2; + + ulong udiff = uop1 - uop2; + long sdiff = unchecked((long)udiff); + + return sdiff >> 1; + } + + public static ulong FusedSubtractHalving(ulong op1, ulong op2) + { + ulong diff = op1 - op2; + bool overflow = op1 < op2; + return (diff >> 1) + (overflow ? 1UL << 63 : 0); + } + + public static uint FusedAddRoundedHalving(uint op1, uint op2) => (uint)((ulong)((ulong)op1 + (ulong)op2 + 1) >> 1); public static uint FusedSubtractHalving(uint op1, uint op2) => (uint)((ulong)((ulong)op1 - (ulong)op2) >> 1); diff --git a/src/runtime/src/tests/JIT/Regression/JitBlue/Runtime_106338/Runtime_106338.cs b/src/runtime/src/tests/JIT/Regression/JitBlue/Runtime_106338/Runtime_106338.cs index 450c002a5d9..b3d4667c075 100644 --- a/src/runtime/src/tests/JIT/Regression/JitBlue/Runtime_106338/Runtime_106338.cs +++ b/src/runtime/src/tests/JIT/Regression/JitBlue/Runtime_106338/Runtime_106338.cs @@ -8,21 +8,74 @@ // Debug: Outputs 1600094603 // Release: Outputs 1600094604 using System; +using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Intrinsics.X86; using Xunit; public class Runtime_106338 { + [MethodImpl(MethodImplOptions.NoInlining)] + static float CastToFloatDirect(long val) => (float)val; + + [MethodImpl(MethodImplOptions.NoInlining)] + static float CastToFloatDirect(ulong val) => (float)val; + + [MethodImpl(MethodImplOptions.NoInlining)] + static float CastToFloatThroughDouble(long val) => (float)(double)val; + + [MethodImpl(MethodImplOptions.NoInlining)] + static float CastToFloatThroughDouble(ulong val) => (float)(double)val; + [Fact] [SkipOnMono("https://github.com/dotnet/runtime/issues/100368", TestPlatforms.Any)] public static void TestEntryPoint() { - ulong vr10 = 16105307123914158031UL; - float vr11 = 4294967295U | vr10; - uint result = BitConverter.SingleToUInt32Bits(vr11); + ulong vr10 = 0xDF818B7F_FFFFFFFF; + float vr11 = vr10; + float vr12 = (float)(double)vr10; + + // These results will be const folded + uint resultDirect = BitConverter.SingleToUInt32Bits(vr11); + uint resultIntermediate = BitConverter.SingleToUInt32Bits(vr12); // Expected to cast ulong -> float directly - Assert.Equal(1600094603U, result); + Assert.Equal(1600094603U, resultDirect); + + // Expected to preserve ulong -> double intermediate cast + Assert.Equal(1600094604U, resultIntermediate); + + // Check that run-time computed values match + resultDirect = BitConverter.SingleToUInt32Bits(CastToFloatDirect(vr10)); + resultIntermediate = BitConverter.SingleToUInt32Bits(CastToFloatThroughDouble(vr10)); + + Assert.Equal(1600094603U, resultDirect); + Assert.Equal(1600094604U, resultIntermediate); + } + + [Fact] + [SkipOnMono("https://github.com/dotnet/runtime/issues/100368", TestPlatforms.Any)] + public static void TestEntryPointSigned() + { + long vr10 = 0x002FFFFF_DFFFFFFF; + float vr11 = vr10; + float vr12 = (float)(double)vr10; + + // These results will be const folded + uint resultDirect = BitConverter.SingleToUInt32Bits(vr11); + uint resultIntermediate = BitConverter.SingleToUInt32Bits(vr12); + + // Expected to cast long -> float directly + Assert.Equal(1514143743U, resultDirect); + + // Expected to preserve long -> double intermediate cast + Assert.Equal(1514143744U, resultIntermediate); + + // Check that run-time computed values match + resultDirect = BitConverter.SingleToUInt32Bits(CastToFloatDirect(vr10)); + resultIntermediate = BitConverter.SingleToUInt32Bits(CastToFloatThroughDouble(vr10)); + + Assert.Equal(1514143743U, resultDirect); + Assert.Equal(1514143744U, resultIntermediate); } } \ No newline at end of file diff --git a/src/runtime/src/tests/async/synchronization-context/synchronization-context.cs b/src/runtime/src/tests/async/synchronization-context/synchronization-context.cs new file mode 100644 index 00000000000..e028ee09c9b --- /dev/null +++ b/src/runtime/src/tests/async/synchronization-context/synchronization-context.cs @@ -0,0 +1,107 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Diagnostics; +using System.Runtime.CompilerServices; +using System.Threading; +using System.Threading.Tasks; +using Xunit; + +public class Async2SynchronizationContext +{ + [Fact] + public static void TestSyncContexts() + { + SynchronizationContext prevContext = SynchronizationContext.Current; + try + { + SynchronizationContext.SetSynchronizationContext(new MySyncContext()); + TestSyncContext().GetAwaiter().GetResult(); + } + finally + { + SynchronizationContext.SetSynchronizationContext(prevContext); + } + } + + private static async Task TestSyncContext() + { + MySyncContext context = (MySyncContext)SynchronizationContext.Current; + await WrappedYieldToThreadPool(suspend: false); + Assert.Same(context, SynchronizationContext.Current); + + await WrappedYieldToThreadPool(suspend: true); + Assert.Same(context, SynchronizationContext.Current); + + await WrappedYieldToThreadPool(suspend: true).ConfigureAwait(true); + Assert.Same(context, SynchronizationContext.Current); + + await WrappedYieldToThreadPool(suspend: false).ConfigureAwait(false); + Assert.Same(context, SynchronizationContext.Current); + + await WrappedYieldToThreadPool(suspend: true).ConfigureAwait(false); + Assert.Null(SynchronizationContext.Current); + + await WrappedYieldToThreadWithCustomSyncContext(); + Assert.Null(SynchronizationContext.Current); + } + + private static async Task WrappedYieldToThreadPool(bool suspend) + { + if (suspend) + { + await Task.Yield(); + } + } + + private static async Task WrappedYieldToThreadWithCustomSyncContext() + { + Assert.Null(SynchronizationContext.Current); + await new YieldToThreadWithCustomSyncContext(); + Assert.True(SynchronizationContext.Current is MySyncContext { }); + } + + private class MySyncContext : SynchronizationContext + { + public override void Post(SendOrPostCallback d, object state) + { + ThreadPool.UnsafeQueueUserWorkItem(_ => + { + SynchronizationContext prevContext = Current; + try + { + SetSynchronizationContext(this); + d(state); + } + finally + { + SetSynchronizationContext(prevContext); + } + }, null); + } + } + + private struct YieldToThreadWithCustomSyncContext : ICriticalNotifyCompletion + { + public YieldToThreadWithCustomSyncContext GetAwaiter() => this; + + public void UnsafeOnCompleted(Action continuation) + { + new Thread(state => + { + SynchronizationContext.SetSynchronizationContext(new MySyncContext()); + continuation(); + }).Start(); + } + + public void OnCompleted(Action continuation) + { + throw new NotImplementedException(); + } + + public bool IsCompleted => false; + + public void GetResult() { } + } +} diff --git a/src/runtime/src/tests/async/synchronization-context/synchronization-context.csproj b/src/runtime/src/tests/async/synchronization-context/synchronization-context.csproj new file mode 100644 index 00000000000..1ae294349c3 --- /dev/null +++ b/src/runtime/src/tests/async/synchronization-context/synchronization-context.csproj @@ -0,0 +1,8 @@ + + + True + + + + + diff --git a/src/source-manifest.json b/src/source-manifest.json index c942482da9d..31b62a30886 100644 --- a/src/source-manifest.json +++ b/src/source-manifest.json @@ -85,10 +85,10 @@ "commitSha": "714a51c57430dab50b67e5b468016288f5f7b0bd" }, { - "barId": 275054, + "barId": 275159, "path": "runtime", "remoteUri": "https://github.com/dotnet/runtime", - "commitSha": "9c0555e89d91149226cfade4a395e02b8d9401ff" + "commitSha": "ede442a9233fb67b2af40709a7d23418e0e491e5" }, { "barId": 273704, From 03413ecec196156f8d19e46dfe20ef95982384b5 Mon Sep 17 00:00:00 2001 From: Michael Simons Date: Tue, 15 Jul 2025 11:08:49 -0500 Subject: [PATCH 08/18] Adjust sdk diff pipeline triggers to increase run frequency (#1496) --- eng/pipelines/source-build-sdk-diff-tests.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/eng/pipelines/source-build-sdk-diff-tests.yml b/eng/pipelines/source-build-sdk-diff-tests.yml index 351cfefbfb6..38075f307ee 100644 --- a/eng/pipelines/source-build-sdk-diff-tests.yml +++ b/eng/pipelines/source-build-sdk-diff-tests.yml @@ -18,6 +18,11 @@ resources: include: - refs/heads/release/*.0.1xx-preview* - refs/heads/internal/release/*.0.1xx* + # Trigger on build stages vs successful pipeline completion for a higher run frequency when there are + # publish/validation failures. + stages: + - VMR_Vertical_Build + - VMR_SourceOnly_Build - pipeline: dotnet-source-build-pre10.0 source: dotnet-source-build-pre10.0 From 549ebad4965586dee68933c854a492e4e9064f7c Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Wed, 16 Jul 2025 13:27:24 +0000 Subject: [PATCH 09/18] [main] Source code updates from dotnet/aspnetcore (#1507) [main] Source code updates from dotnet/aspnetcore --- src/aspnetcore/eng/Versions.props | 4 ++-- .../src/SourceGenerators/PublicTopLevelProgramGenerator.cs | 5 +++-- .../SourceGenerators/PublicTopLevelProgramGeneratorTests.cs | 5 +++-- .../src/OpenApi/gen/XmlCommentGenerator.Emitter.cs | 2 ++ ...AddOpenApi#OpenApiXmlCommentSupport.generated.verified.cs | 4 +++- ...ionalTexts#OpenApiXmlCommentSupport.generated.verified.cs | 4 +++- ...sOnSchemas#OpenApiXmlCommentSupport.generated.verified.cs | 4 +++- ...ontrollers#OpenApiXmlCommentSupport.generated.verified.cs | 4 +++- ...inimalApis#OpenApiXmlCommentSupport.generated.verified.cs | 4 +++- ...sOnSchemas#OpenApiXmlCommentSupport.generated.verified.cs | 4 +++- ...nIdFormats#OpenApiXmlCommentSupport.generated.verified.cs | 2 ++ src/source-manifest.json | 4 ++-- 12 files changed, 32 insertions(+), 14 deletions(-) diff --git a/src/aspnetcore/eng/Versions.props b/src/aspnetcore/eng/Versions.props index f44e9ed54b4..753929a5dd1 100644 --- a/src/aspnetcore/eng/Versions.props +++ b/src/aspnetcore/eng/Versions.props @@ -325,8 +325,8 @@ $(XunitVersion) $(XunitVersion) 5.2.2 - 2.0.0-preview.29 - 2.0.0-preview.29 + 2.0.0 + 2.0.0 6.0.322601 1.10.93 diff --git a/src/aspnetcore/src/Framework/AspNetCoreAnalyzers/src/SourceGenerators/PublicTopLevelProgramGenerator.cs b/src/aspnetcore/src/Framework/AspNetCoreAnalyzers/src/SourceGenerators/PublicTopLevelProgramGenerator.cs index 7e3f3eacd95..77b95a4b507 100644 --- a/src/aspnetcore/src/Framework/AspNetCoreAnalyzers/src/SourceGenerators/PublicTopLevelProgramGenerator.cs +++ b/src/aspnetcore/src/Framework/AspNetCoreAnalyzers/src/SourceGenerators/PublicTopLevelProgramGenerator.cs @@ -12,9 +12,10 @@ public class PublicProgramSourceGenerator : IIncrementalGenerator { private const string PublicPartialProgramClassSource = """ // -#pragma warning disable CS1591 +/// +/// Auto-generated public partial Program class for top-level statement apps. +/// public partial class Program { } -#pragma warning restore CS1591 """; public void Initialize(IncrementalGeneratorInitializationContext context) diff --git a/src/aspnetcore/src/Framework/AspNetCoreAnalyzers/test/SourceGenerators/PublicTopLevelProgramGeneratorTests.cs b/src/aspnetcore/src/Framework/AspNetCoreAnalyzers/test/SourceGenerators/PublicTopLevelProgramGeneratorTests.cs index 173dfa7469f..a75a34057fd 100644 --- a/src/aspnetcore/src/Framework/AspNetCoreAnalyzers/test/SourceGenerators/PublicTopLevelProgramGeneratorTests.cs +++ b/src/aspnetcore/src/Framework/AspNetCoreAnalyzers/test/SourceGenerators/PublicTopLevelProgramGeneratorTests.cs @@ -9,9 +9,10 @@ public class PublicTopLevelProgramGeneratorTests { private const string ExpectedGeneratedSource = """ // -#pragma warning disable CS1591 +/// +/// Auto-generated public partial Program class for top-level statement apps. +/// public partial class Program { } -#pragma warning restore CS1591 """; [Fact] diff --git a/src/aspnetcore/src/OpenApi/gen/XmlCommentGenerator.Emitter.cs b/src/aspnetcore/src/OpenApi/gen/XmlCommentGenerator.Emitter.cs index 6f6d16d4146..cf8bb5e875e 100644 --- a/src/aspnetcore/src/OpenApi/gen/XmlCommentGenerator.Emitter.cs +++ b/src/aspnetcore/src/OpenApi/gen/XmlCommentGenerator.Emitter.cs @@ -93,6 +93,7 @@ private static Dictionary GenerateCacheEntries() } } + {{GeneratedCodeAttribute}} file static class DocumentationCommentIdHelper { /// @@ -471,6 +472,7 @@ public Task TransformAsync(OpenApiSchema schema, OpenApiSchemaTransformerContext } } + {{GeneratedCodeAttribute}} file static class JsonNodeExtensions { public static JsonNode? Parse(this string? json) diff --git a/src/aspnetcore/src/OpenApi/test/Microsoft.AspNetCore.OpenApi.SourceGenerators.Tests/snapshots/AddOpenApiTests.CanInterceptAddOpenApi#OpenApiXmlCommentSupport.generated.verified.cs b/src/aspnetcore/src/OpenApi/test/Microsoft.AspNetCore.OpenApi.SourceGenerators.Tests/snapshots/AddOpenApiTests.CanInterceptAddOpenApi#OpenApiXmlCommentSupport.generated.verified.cs index f13f5ffc8c8..dea5968bdf6 100644 --- a/src/aspnetcore/src/OpenApi/test/Microsoft.AspNetCore.OpenApi.SourceGenerators.Tests/snapshots/AddOpenApiTests.CanInterceptAddOpenApi#OpenApiXmlCommentSupport.generated.verified.cs +++ b/src/aspnetcore/src/OpenApi/test/Microsoft.AspNetCore.OpenApi.SourceGenerators.Tests/snapshots/AddOpenApiTests.CanInterceptAddOpenApi#OpenApiXmlCommentSupport.generated.verified.cs @@ -75,6 +75,7 @@ private static Dictionary GenerateCacheEntries() } } + [System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.AspNetCore.OpenApi.SourceGenerators, Version=42.42.42.42, Culture=neutral, PublicKeyToken=adb9793829ddae60", "42.42.42.42")] file static class DocumentationCommentIdHelper { /// @@ -453,6 +454,7 @@ public Task TransformAsync(OpenApiSchema schema, OpenApiSchemaTransformerContext } } + [System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.AspNetCore.OpenApi.SourceGenerators, Version=42.42.42.42, Culture=neutral, PublicKeyToken=adb9793829ddae60", "42.42.42.42")] file static class JsonNodeExtensions { public static JsonNode? Parse(this string? json) @@ -527,4 +529,4 @@ public static IServiceCollection AddOpenApi(this IServiceCollection services, st } } -} \ No newline at end of file +} diff --git a/src/aspnetcore/src/OpenApi/test/Microsoft.AspNetCore.OpenApi.SourceGenerators.Tests/snapshots/AdditionalTextsTests.CanHandleXmlForSchemasInAdditionalTexts#OpenApiXmlCommentSupport.generated.verified.cs b/src/aspnetcore/src/OpenApi/test/Microsoft.AspNetCore.OpenApi.SourceGenerators.Tests/snapshots/AdditionalTextsTests.CanHandleXmlForSchemasInAdditionalTexts#OpenApiXmlCommentSupport.generated.verified.cs index ed5d669b673..fe18f3d0de2 100644 --- a/src/aspnetcore/src/OpenApi/test/Microsoft.AspNetCore.OpenApi.SourceGenerators.Tests/snapshots/AdditionalTextsTests.CanHandleXmlForSchemasInAdditionalTexts#OpenApiXmlCommentSupport.generated.verified.cs +++ b/src/aspnetcore/src/OpenApi/test/Microsoft.AspNetCore.OpenApi.SourceGenerators.Tests/snapshots/AdditionalTextsTests.CanHandleXmlForSchemasInAdditionalTexts#OpenApiXmlCommentSupport.generated.verified.cs @@ -104,6 +104,7 @@ private static Dictionary GenerateCacheEntries() } } + [System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.AspNetCore.OpenApi.SourceGenerators, Version=42.42.42.42, Culture=neutral, PublicKeyToken=adb9793829ddae60", "42.42.42.42")] file static class DocumentationCommentIdHelper { /// @@ -482,6 +483,7 @@ public Task TransformAsync(OpenApiSchema schema, OpenApiSchemaTransformerContext } } + [System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.AspNetCore.OpenApi.SourceGenerators, Version=42.42.42.42, Culture=neutral, PublicKeyToken=adb9793829ddae60", "42.42.42.42")] file static class JsonNodeExtensions { public static JsonNode? Parse(this string? json) @@ -524,4 +526,4 @@ public static IServiceCollection AddOpenApi(this IServiceCollection services) } } -} \ No newline at end of file +} diff --git a/src/aspnetcore/src/OpenApi/test/Microsoft.AspNetCore.OpenApi.SourceGenerators.Tests/snapshots/CompletenessTests.SupportsAllXmlTagsOnSchemas#OpenApiXmlCommentSupport.generated.verified.cs b/src/aspnetcore/src/OpenApi/test/Microsoft.AspNetCore.OpenApi.SourceGenerators.Tests/snapshots/CompletenessTests.SupportsAllXmlTagsOnSchemas#OpenApiXmlCommentSupport.generated.verified.cs index a70de5ef5d3..69e1bbcab4b 100644 --- a/src/aspnetcore/src/OpenApi/test/Microsoft.AspNetCore.OpenApi.SourceGenerators.Tests/snapshots/CompletenessTests.SupportsAllXmlTagsOnSchemas#OpenApiXmlCommentSupport.generated.verified.cs +++ b/src/aspnetcore/src/OpenApi/test/Microsoft.AspNetCore.OpenApi.SourceGenerators.Tests/snapshots/CompletenessTests.SupportsAllXmlTagsOnSchemas#OpenApiXmlCommentSupport.generated.verified.cs @@ -196,6 +196,7 @@ method as a cref attribute. } } + [System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.AspNetCore.OpenApi.SourceGenerators, Version=42.42.42.42, Culture=neutral, PublicKeyToken=adb9793829ddae60", "42.42.42.42")] file static class DocumentationCommentIdHelper { /// @@ -574,6 +575,7 @@ public Task TransformAsync(OpenApiSchema schema, OpenApiSchemaTransformerContext } } + [System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.AspNetCore.OpenApi.SourceGenerators, Version=42.42.42.42, Culture=neutral, PublicKeyToken=adb9793829ddae60", "42.42.42.42")] file static class JsonNodeExtensions { public static JsonNode? Parse(this string? json) @@ -616,4 +618,4 @@ public static IServiceCollection AddOpenApi(this IServiceCollection services) } } -} \ No newline at end of file +} diff --git a/src/aspnetcore/src/OpenApi/test/Microsoft.AspNetCore.OpenApi.SourceGenerators.Tests/snapshots/OperationTests.SupportsXmlCommentsOnOperationsFromControllers#OpenApiXmlCommentSupport.generated.verified.cs b/src/aspnetcore/src/OpenApi/test/Microsoft.AspNetCore.OpenApi.SourceGenerators.Tests/snapshots/OperationTests.SupportsXmlCommentsOnOperationsFromControllers#OpenApiXmlCommentSupport.generated.verified.cs index f4da876e212..4baa534fd17 100644 --- a/src/aspnetcore/src/OpenApi/test/Microsoft.AspNetCore.OpenApi.SourceGenerators.Tests/snapshots/OperationTests.SupportsXmlCommentsOnOperationsFromControllers#OpenApiXmlCommentSupport.generated.verified.cs +++ b/src/aspnetcore/src/OpenApi/test/Microsoft.AspNetCore.OpenApi.SourceGenerators.Tests/snapshots/OperationTests.SupportsXmlCommentsOnOperationsFromControllers#OpenApiXmlCommentSupport.generated.verified.cs @@ -79,6 +79,7 @@ private static Dictionary GenerateCacheEntries() } } + [System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.AspNetCore.OpenApi.SourceGenerators, Version=42.42.42.42, Culture=neutral, PublicKeyToken=adb9793829ddae60", "42.42.42.42")] file static class DocumentationCommentIdHelper { /// @@ -457,6 +458,7 @@ public Task TransformAsync(OpenApiSchema schema, OpenApiSchemaTransformerContext } } + [System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.AspNetCore.OpenApi.SourceGenerators, Version=42.42.42.42, Culture=neutral, PublicKeyToken=adb9793829ddae60", "42.42.42.42")] file static class JsonNodeExtensions { public static JsonNode? Parse(this string? json) @@ -499,4 +501,4 @@ public static IServiceCollection AddOpenApi(this IServiceCollection services) } } -} \ No newline at end of file +} diff --git a/src/aspnetcore/src/OpenApi/test/Microsoft.AspNetCore.OpenApi.SourceGenerators.Tests/snapshots/OperationTests.SupportsXmlCommentsOnOperationsFromMinimalApis#OpenApiXmlCommentSupport.generated.verified.cs b/src/aspnetcore/src/OpenApi/test/Microsoft.AspNetCore.OpenApi.SourceGenerators.Tests/snapshots/OperationTests.SupportsXmlCommentsOnOperationsFromMinimalApis#OpenApiXmlCommentSupport.generated.verified.cs index 4a2aa376b29..fc1fbec8ab3 100644 --- a/src/aspnetcore/src/OpenApi/test/Microsoft.AspNetCore.OpenApi.SourceGenerators.Tests/snapshots/OperationTests.SupportsXmlCommentsOnOperationsFromMinimalApis#OpenApiXmlCommentSupport.generated.verified.cs +++ b/src/aspnetcore/src/OpenApi/test/Microsoft.AspNetCore.OpenApi.SourceGenerators.Tests/snapshots/OperationTests.SupportsXmlCommentsOnOperationsFromMinimalApis#OpenApiXmlCommentSupport.generated.verified.cs @@ -97,6 +97,7 @@ private static Dictionary GenerateCacheEntries() } } + [System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.AspNetCore.OpenApi.SourceGenerators, Version=42.42.42.42, Culture=neutral, PublicKeyToken=adb9793829ddae60", "42.42.42.42")] file static class DocumentationCommentIdHelper { /// @@ -475,6 +476,7 @@ public Task TransformAsync(OpenApiSchema schema, OpenApiSchemaTransformerContext } } + [System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.AspNetCore.OpenApi.SourceGenerators, Version=42.42.42.42, Culture=neutral, PublicKeyToken=adb9793829ddae60", "42.42.42.42")] file static class JsonNodeExtensions { public static JsonNode? Parse(this string? json) @@ -517,4 +519,4 @@ public static IServiceCollection AddOpenApi(this IServiceCollection services) } } -} \ No newline at end of file +} diff --git a/src/aspnetcore/src/OpenApi/test/Microsoft.AspNetCore.OpenApi.SourceGenerators.Tests/snapshots/SchemaTests.SupportsXmlCommentsOnSchemas#OpenApiXmlCommentSupport.generated.verified.cs b/src/aspnetcore/src/OpenApi/test/Microsoft.AspNetCore.OpenApi.SourceGenerators.Tests/snapshots/SchemaTests.SupportsXmlCommentsOnSchemas#OpenApiXmlCommentSupport.generated.verified.cs index 92cc5419f37..33e3e561e95 100644 --- a/src/aspnetcore/src/OpenApi/test/Microsoft.AspNetCore.OpenApi.SourceGenerators.Tests/snapshots/SchemaTests.SupportsXmlCommentsOnSchemas#OpenApiXmlCommentSupport.generated.verified.cs +++ b/src/aspnetcore/src/OpenApi/test/Microsoft.AspNetCore.OpenApi.SourceGenerators.Tests/snapshots/SchemaTests.SupportsXmlCommentsOnSchemas#OpenApiXmlCommentSupport.generated.verified.cs @@ -105,6 +105,7 @@ private static Dictionary GenerateCacheEntries() } } + [System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.AspNetCore.OpenApi.SourceGenerators, Version=42.42.42.42, Culture=neutral, PublicKeyToken=adb9793829ddae60", "42.42.42.42")] file static class DocumentationCommentIdHelper { /// @@ -483,6 +484,7 @@ public Task TransformAsync(OpenApiSchema schema, OpenApiSchemaTransformerContext } } + [System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.AspNetCore.OpenApi.SourceGenerators, Version=42.42.42.42, Culture=neutral, PublicKeyToken=adb9793829ddae60", "42.42.42.42")] file static class JsonNodeExtensions { public static JsonNode? Parse(this string? json) @@ -525,4 +527,4 @@ public static IServiceCollection AddOpenApi(this IServiceCollection services) } } -} \ No newline at end of file +} diff --git a/src/aspnetcore/src/OpenApi/test/Microsoft.AspNetCore.OpenApi.SourceGenerators.Tests/snapshots/XmlCommentDocumentationIdTests.CanMergeXmlCommentsWithDifferentDocumentationIdFormats#OpenApiXmlCommentSupport.generated.verified.cs b/src/aspnetcore/src/OpenApi/test/Microsoft.AspNetCore.OpenApi.SourceGenerators.Tests/snapshots/XmlCommentDocumentationIdTests.CanMergeXmlCommentsWithDifferentDocumentationIdFormats#OpenApiXmlCommentSupport.generated.verified.cs index 5c3dcf38228..fb09682caf3 100644 --- a/src/aspnetcore/src/OpenApi/test/Microsoft.AspNetCore.OpenApi.SourceGenerators.Tests/snapshots/XmlCommentDocumentationIdTests.CanMergeXmlCommentsWithDifferentDocumentationIdFormats#OpenApiXmlCommentSupport.generated.verified.cs +++ b/src/aspnetcore/src/OpenApi/test/Microsoft.AspNetCore.OpenApi.SourceGenerators.Tests/snapshots/XmlCommentDocumentationIdTests.CanMergeXmlCommentsWithDifferentDocumentationIdFormats#OpenApiXmlCommentSupport.generated.verified.cs @@ -76,6 +76,7 @@ private static Dictionary GenerateCacheEntries() } } + [System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.AspNetCore.OpenApi.SourceGenerators, Version=42.42.42.42, Culture=neutral, PublicKeyToken=adb9793829ddae60", "42.42.42.42")] file static class DocumentationCommentIdHelper { /// @@ -454,6 +455,7 @@ public Task TransformAsync(OpenApiSchema schema, OpenApiSchemaTransformerContext } } + [System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.AspNetCore.OpenApi.SourceGenerators, Version=42.42.42.42, Culture=neutral, PublicKeyToken=adb9793829ddae60", "42.42.42.42")] file static class JsonNodeExtensions { public static JsonNode? Parse(this string? json) diff --git a/src/source-manifest.json b/src/source-manifest.json index 31b62a30886..8da8c90349c 100644 --- a/src/source-manifest.json +++ b/src/source-manifest.json @@ -7,10 +7,10 @@ "commitSha": "4e526204e83e615efe8eb5743be7fbccfa4e492a" }, { - "barId": 275166, + "barId": 275303, "path": "aspnetcore", "remoteUri": "https://github.com/dotnet/aspnetcore", - "commitSha": "170f046b314bbbc67f6771b6eb7c2ed50859e633" + "commitSha": "9d4270cd93259b2ad6740bd8bb8315615ce93c94" }, { "barId": 273742, From 09c7c7496e2348d25f6cc270eed5ca25629d82f8 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Wed, 16 Jul 2025 13:27:29 +0000 Subject: [PATCH 10/18] [main] Source code updates from microsoft/vstest (#1509) [main] Source code updates from microsoft/vstest --- src/source-manifest.json | 4 +- src/vstest/.github/dependabot.yml | 12 + src/vstest/Directory.Build.props | 13 +- src/vstest/azure-pipelines.yml | 1 + src/vstest/docs/contribute.md | 2 +- src/vstest/dotnet.config | 2 + src/vstest/eng/Version.Details.xml | 8 +- src/vstest/eng/Versions.props | 22 +- src/vstest/eng/common/CIBuild.cmd | 2 +- src/vstest/eng/common/build.ps1 | 11 +- src/vstest/eng/common/build.sh | 33 +- src/vstest/eng/common/cibuild.sh | 2 +- .../eng/common/core-templates/job/job.yml | 42 +-- .../common/core-templates/job/onelocbuild.yml | 5 +- .../job/publish-build-assets.yml | 66 +++- .../core-templates/job/source-build.yml | 5 +- .../job/source-index-stage1.yml | 47 +-- .../core-templates/jobs/codeql-build.yml | 1 - .../eng/common/core-templates/jobs/jobs.yml | 12 +- .../core-templates/jobs/source-build.yml | 2 +- .../core-templates/post-build/post-build.yml | 9 +- .../steps/cleanup-microbuild.yml | 28 ++ .../core-templates/steps/generate-sbom.yml | 2 +- .../steps/get-delegation-sas.yml | 11 +- .../steps/install-microbuild.yml | 54 +++ .../core-templates/steps/publish-logs.yml | 3 + .../core-templates/steps/source-build.yml | 81 +---- .../steps/source-index-stage1-publish.yml | 35 ++ .../eng/common/cross/arm64/tizen/tizen.patch | 2 +- .../eng/common/cross/armel/armel.jessie.patch | 43 --- .../eng/common/cross/build-android-rootfs.sh | 49 ++- src/vstest/eng/common/cross/build-rootfs.sh | 237 ++++++++----- src/vstest/eng/common/cross/install-debs.py | 334 ++++++++++++++++++ src/vstest/eng/common/cross/tizen-fetch.sh | 9 +- src/vstest/eng/common/cross/toolchain.cmake | 82 ++--- src/vstest/eng/common/darc-init.sh | 2 +- src/vstest/eng/common/dotnet.cmd | 7 + src/vstest/eng/common/dotnet.ps1 | 11 + src/vstest/eng/common/dotnet.sh | 26 ++ src/vstest/eng/common/internal/NuGet.config | 3 + .../eng/common/native/install-dependencies.sh | 62 ++++ .../common/post-build/publish-using-darc.ps1 | 7 +- src/vstest/eng/common/sdk-task.ps1 | 9 +- src/vstest/eng/common/sdk-task.sh | 116 ++++++ src/vstest/eng/common/sdl/packages.config | 2 +- .../eng/common/templates-official/job/job.yml | 4 +- .../steps/publish-build-artifacts.yml | 7 +- .../steps/source-index-stage1-publish.yml | 7 + src/vstest/eng/common/templates/job/job.yml | 4 +- .../steps/publish-build-artifacts.yml | 8 +- .../steps/source-index-stage1-publish.yml | 7 + .../eng/common/templates/steps/vmr-sync.yml | 207 +++++++++++ .../eng/common/templates/vmr-build-pr.yml | 42 +++ src/vstest/eng/common/tools.ps1 | 47 +-- src/vstest/eng/common/tools.sh | 49 ++- src/vstest/eng/common/vmr-sync.ps1 | 138 ++++++++ src/vstest/eng/common/vmr-sync.sh | 207 +++++++++++ src/vstest/eng/verify-nupkgs.ps1 | 4 +- src/vstest/global.json | 12 +- .../TestPlatform.Playground.csproj | 16 +- .../ExternalAssemblyVersions.cs | 2 +- .../Hosting/DotnetTestHostManager.cs | 116 +++++- .../VsTestConsoleRequestSender.cs | 4 +- .../Microsoft.CodeCoverage.csproj | 19 +- .../Microsoft.CodeCoverage.nuspec | 63 +--- .../Microsoft.TestPlatform.csproj | 17 +- .../Microsoft.TestPlatform.nuspec | 81 +---- ...tudio.TestTools.TestPlatform.V2.CLI.csproj | 20 -- src/vstest/src/testhost.x86/app.config | 12 +- .../TestPlatformHelpers/TestRequestManager.cs | 1 + src/vstest/src/vstest.console/app.config | 4 +- ...ensions.EventLogCollector.UnitTests.csproj | 1 + src/vstest/test/Directory.Build.props | 11 + .../.runsettings | 5 + .../Build.cs | 12 +- .../CUITTest.cs | 37 -- .../DotnetTestMSBuildOutputTests.cs | 7 +- .../DotnetTestTests.cs | 12 +- ...latform.Acceptance.IntegrationTests.csproj | 3 +- .../Program.cs | 13 - .../RunsettingsTests.cs | 8 +- .../TestPlatformNugetPackageTests.cs | 1 + .../CustomTestHostTests.cs | 27 +- ...RunTestsWithDifferentConfigurationTests.cs | 68 +++- ...Platform.AdapterUtilities.UnitTests.csproj | 2 +- .../Program.cs | 11 - ...rosoft.TestPlatform.Build.UnitTests.csproj | 2 +- .../Program.cs | 11 - ...osoft.TestPlatform.Client.UnitTests.csproj | 2 +- .../Program.cs | 11 - ...osoft.TestPlatform.Common.UnitTests.csproj | 2 +- .../Program.cs | 11 - ...icationUtilities.Platform.UnitTests.csproj | 2 +- .../Program.cs | 11 - ...rm.CommunicationUtilities.UnitTests.csproj | 2 +- .../Program.cs | 11 - .../Helpers/DotnetHostHelperTest.cs | 2 + ...estPlatform.CoreUtilities.UnitTests.csproj | 2 +- .../Program.cs | 14 - .../Discovery/DiscovererEnumeratorTests.cs | 4 +- .../Execution/RunTestsWithSourcesTests.cs | 1 + ...tPlatform.CrossPlatEngine.UnitTests.csproj | 2 +- .../Program.cs | 11 - ...nsions.BlameDataCollector.UnitTests.csproj | 2 +- .../Program.cs | 11 - ...orm.Extensions.HtmlLogger.UnitTests.csproj | 2 +- .../Program.cs | 11 - ...form.Extensions.TrxLogger.UnitTests.csproj | 2 +- .../Program.cs | 11 - ....TestPlatform.ObjectModel.UnitTests.csproj | 2 +- .../Program.cs | 11 - .../RunSettings/RunConfigurationTests.cs | 10 +- .../Hosting/DotnetTestHostManagerTests.cs | 1 - ...Platform.TestHostProvider.UnitTests.csproj | 2 +- .../Program.cs | 11 - .../IntegrationTestBase.cs | 21 +- ...ft.TestPlatform.Utilities.UnitTests.csproj | 2 +- .../Program.cs | 11 - .../SettingsMigrator.UnitTests.csproj | 1 + .../TestAssets/ArchitectureSwitch/global.json | 5 - .../CUITTestProject/CUITTestProject.csproj | 47 --- .../CUITTestProject/CodedUITest1.cs | 18 - .../BingWebTest/BingWebTest.csproj | 19 - src/vstest/test/TestAssets/TestAssets.sln | 6 - .../TranslationLayer.UnitTests/Program.cs | 11 - .../TranslationLayer.UnitTests.csproj | 2 +- .../datacollector.PlatformTests/Program.cs | 14 - .../test/datacollector.UnitTests/Program.cs | 14 - .../datacollector.UnitTests.csproj | 2 +- src/vstest/test/testhost.UnitTests/Program.cs | 11 - .../testhost.UnitTests.csproj | 2 +- .../vstest.ProgrammerTests.csproj | 1 - .../test/vstest.console.UnitTests/Program.cs | 11 - .../vstest.console.UnitTests.csproj | 2 +- 134 files changed, 2061 insertions(+), 1148 deletions(-) create mode 100644 src/vstest/.github/dependabot.yml create mode 100644 src/vstest/dotnet.config create mode 100644 src/vstest/eng/common/core-templates/steps/cleanup-microbuild.yml create mode 100644 src/vstest/eng/common/core-templates/steps/install-microbuild.yml create mode 100644 src/vstest/eng/common/core-templates/steps/source-index-stage1-publish.yml delete mode 100644 src/vstest/eng/common/cross/armel/armel.jessie.patch create mode 100644 src/vstest/eng/common/cross/install-debs.py create mode 100644 src/vstest/eng/common/dotnet.cmd create mode 100644 src/vstest/eng/common/dotnet.ps1 create mode 100644 src/vstest/eng/common/dotnet.sh create mode 100644 src/vstest/eng/common/native/install-dependencies.sh create mode 100644 src/vstest/eng/common/sdk-task.sh create mode 100644 src/vstest/eng/common/templates-official/steps/source-index-stage1-publish.yml create mode 100644 src/vstest/eng/common/templates/steps/source-index-stage1-publish.yml create mode 100644 src/vstest/eng/common/templates/steps/vmr-sync.yml create mode 100644 src/vstest/eng/common/templates/vmr-build-pr.yml create mode 100644 src/vstest/eng/common/vmr-sync.ps1 create mode 100644 src/vstest/eng/common/vmr-sync.sh create mode 100644 src/vstest/test/Microsoft.TestPlatform.Acceptance.IntegrationTests/.runsettings delete mode 100644 src/vstest/test/Microsoft.TestPlatform.Acceptance.IntegrationTests/CUITTest.cs delete mode 100644 src/vstest/test/Microsoft.TestPlatform.Acceptance.IntegrationTests/Program.cs delete mode 100644 src/vstest/test/Microsoft.TestPlatform.AdapterUtilities.UnitTests/Program.cs delete mode 100644 src/vstest/test/Microsoft.TestPlatform.Build.UnitTests/Program.cs delete mode 100644 src/vstest/test/Microsoft.TestPlatform.Client.UnitTests/Program.cs delete mode 100644 src/vstest/test/Microsoft.TestPlatform.Common.UnitTests/Program.cs delete mode 100644 src/vstest/test/Microsoft.TestPlatform.CommunicationUtilities.Platform.UnitTests/Program.cs delete mode 100644 src/vstest/test/Microsoft.TestPlatform.CommunicationUtilities.UnitTests/Program.cs delete mode 100644 src/vstest/test/Microsoft.TestPlatform.CoreUtilities.UnitTests/Program.cs delete mode 100644 src/vstest/test/Microsoft.TestPlatform.CrossPlatEngine.UnitTests/Program.cs delete mode 100644 src/vstest/test/Microsoft.TestPlatform.Extensions.BlameDataCollector.UnitTests/Program.cs delete mode 100644 src/vstest/test/Microsoft.TestPlatform.Extensions.HtmlLogger.UnitTests/Program.cs delete mode 100644 src/vstest/test/Microsoft.TestPlatform.Extensions.TrxLogger.UnitTests/Program.cs delete mode 100644 src/vstest/test/Microsoft.TestPlatform.ObjectModel.UnitTests/Program.cs delete mode 100644 src/vstest/test/Microsoft.TestPlatform.TestHostProvider.UnitTests/Program.cs delete mode 100644 src/vstest/test/Microsoft.TestPlatform.Utilities.UnitTests/Program.cs delete mode 100644 src/vstest/test/TestAssets/ArchitectureSwitch/global.json delete mode 100644 src/vstest/test/TestAssets/CUITTestProject/CUITTestProject.csproj delete mode 100644 src/vstest/test/TestAssets/CUITTestProject/CodedUITest1.cs delete mode 100644 src/vstest/test/TranslationLayer.UnitTests/Program.cs delete mode 100644 src/vstest/test/datacollector.PlatformTests/Program.cs delete mode 100644 src/vstest/test/datacollector.UnitTests/Program.cs delete mode 100644 src/vstest/test/testhost.UnitTests/Program.cs delete mode 100644 src/vstest/test/vstest.console.UnitTests/Program.cs diff --git a/src/source-manifest.json b/src/source-manifest.json index 8da8c90349c..6c5761ba5ba 100644 --- a/src/source-manifest.json +++ b/src/source-manifest.json @@ -127,10 +127,10 @@ "commitSha": "43d52c423e7ed37cf59a01629f9bace5c6bf6f96" }, { - "barId": 272429, + "barId": 275283, "path": "vstest", "remoteUri": "https://github.com/microsoft/vstest", - "commitSha": "cdcfb7f5c163d7b7a555b129522c3b868f73e92c" + "commitSha": "8b102963a8cce7809a6956fe0a6df5cb93b2447a" }, { "barId": 273947, diff --git a/src/vstest/.github/dependabot.yml b/src/vstest/.github/dependabot.yml new file mode 100644 index 00000000000..a1ef8b6a84a --- /dev/null +++ b/src/vstest/.github/dependabot.yml @@ -0,0 +1,12 @@ +version: 2 +updates: + - package-ecosystem: "dotnet-sdk" + directory: "/" + schedule: + interval: "weekly" + day: "wednesday" + ignore: + - dependency-name: "*" + update-types: + - "version-update:semver-major" + - "version-update:semver-minor" diff --git a/src/vstest/Directory.Build.props b/src/vstest/Directory.Build.props index 51ef037d2e2..f8aef037989 100644 --- a/src/vstest/Directory.Build.props +++ b/src/vstest/Directory.Build.props @@ -15,17 +15,6 @@ - - 17.10.0 - - $(TPVersionPrefix)-dev 15.0.0 @@ -147,6 +136,8 @@ MSTest $(TestRunnerAdditionalArguments) --filter "TestCategory!=Windows&TestCategory!=Windows-Review" + + false diff --git a/src/vstest/azure-pipelines.yml b/src/vstest/azure-pipelines.yml index 16723ccbc2f..541b35ce346 100644 --- a/src/vstest/azure-pipelines.yml +++ b/src/vstest/azure-pipelines.yml @@ -112,6 +112,7 @@ stages: -nobl -integrationTest -performanceTest + /bl:$(Build.SourcesDirectory)/artifacts/TestResults/$(_BuildConfig)/Test.binlog name: Test displayName: Test diff --git a/src/vstest/docs/contribute.md b/src/vstest/docs/contribute.md index 2a5100be9d0..05ba93c560e 100644 --- a/src/vstest/docs/contribute.md +++ b/src/vstest/docs/contribute.md @@ -147,7 +147,7 @@ default, `Debug` configuration is run. If you want to run a particular test. Eg: Test Name that contains Blame in Acceptance test ```shell -> test.cmd -p accept -f net451 -filter blame +> .\test.cmd -bl -c release /p:TestRunnerAdditionalArguments="'--filter Blame'" -Integration ``` ## Deployment diff --git a/src/vstest/dotnet.config b/src/vstest/dotnet.config new file mode 100644 index 00000000000..da0410e32d5 --- /dev/null +++ b/src/vstest/dotnet.config @@ -0,0 +1,2 @@ +[dotnet.test.runner] +name = "Microsoft.Testing.Platform" diff --git a/src/vstest/eng/Version.Details.xml b/src/vstest/eng/Version.Details.xml index 7a86e9ff834..185bd6fa6ec 100644 --- a/src/vstest/eng/Version.Details.xml +++ b/src/vstest/eng/Version.Details.xml @@ -2,9 +2,9 @@ - + https://dev.azure.com/devdiv/DevDiv/_git/vs-code-coverage - 414b8035705ca246a1b7331eab02a656b0dc3706 + b3c8a0e7de26919a4efd2a347133522dca5b8ee6 https://github.com/dotnet/dotnet @@ -27,9 +27,9 @@ - + https://github.com/dotnet/arcade - 0d52a8b262d35fa2fde84e398cb2e791b8454bd2 + 4e526204e83e615efe8eb5743be7fbccfa4e492a https://github.com/dotnet/symreader-converter diff --git a/src/vstest/eng/Versions.props b/src/vstest/eng/Versions.props index d00f73e8a71..62571e2c450 100644 --- a/src/vstest/eng/Versions.props +++ b/src/vstest/eng/Versions.props @@ -13,7 +13,7 @@ from appending +, which breaks DTAAgent. --> false - 17.15.0 + 18.0.0 preview @@ -51,13 +51,13 @@ 0.2.631904 6.0.2 6.0.0 - 17.12.0 - 17.14.3-preview.25164.1 + 18.0.0-beta.25364.2 + 17.15.0-preview.25354.5 - 17.13.35723.115 + 18.0.0-preview-1-10811-208 $(MicrosoftVisualStudioDiagnosticsUtilitiesVersion) 17.13.39960 17.13.24 @@ -69,8 +69,9 @@ 8.0.0 4.5.5 8.0.0 - 17.10.0-preview-2-34602-162 - 17.10.0-preview-2-34602-162 + + 18.0.0-preview-1-10811-208 + 18.0.0-preview-1-10811-208 17.12.35519.223 5.0.0 6.1.0 @@ -78,13 +79,14 @@ 8.1.0 + 1.7.2 4.16.1 17.9.0 - 3.4.3 - 3.4.3 + 3.9.3 + 3.9.3 1.0.3-preview 2.4.2 2.4.5 @@ -98,8 +100,8 @@ These versions need to be "statically" readable because we read this file as xml in our build and tests. --> - [3.4.3] - [3.4.3] + [3.9.3] + [3.9.3] [3.3.1] [2.2.10] [2.2.10] diff --git a/src/vstest/eng/common/CIBuild.cmd b/src/vstest/eng/common/CIBuild.cmd index 56c2f25ac22..ac1f72bf94e 100644 --- a/src/vstest/eng/common/CIBuild.cmd +++ b/src/vstest/eng/common/CIBuild.cmd @@ -1,2 +1,2 @@ @echo off -powershell -ExecutionPolicy ByPass -NoProfile -command "& """%~dp0Build.ps1""" -restore -build -test -sign -pack -publish -ci %*" \ No newline at end of file +powershell -ExecutionPolicy ByPass -NoProfile -command "& """%~dp0Build.ps1""" -restore -build -test -sign -pack -publish -ci %*" diff --git a/src/vstest/eng/common/build.ps1 b/src/vstest/eng/common/build.ps1 index 438f9920c43..8cfee107e7a 100644 --- a/src/vstest/eng/common/build.ps1 +++ b/src/vstest/eng/common/build.ps1 @@ -7,6 +7,7 @@ Param( [string] $msbuildEngine = $null, [bool] $warnAsError = $true, [bool] $nodeReuse = $true, + [switch] $buildCheck = $false, [switch][Alias('r')]$restore, [switch] $deployDeps, [switch][Alias('b')]$build, @@ -20,6 +21,7 @@ Param( [switch] $publish, [switch] $clean, [switch][Alias('pb')]$productBuild, + [switch]$fromVMR, [switch][Alias('bl')]$binaryLog, [switch][Alias('nobl')]$excludeCIBinarylog, [switch] $ci, @@ -71,6 +73,9 @@ function Print-Usage() { Write-Host " -msbuildEngine Msbuild engine to use to run build ('dotnet', 'vs', or unspecified)." Write-Host " -excludePrereleaseVS Set to exclude build engines in prerelease versions of Visual Studio" Write-Host " -nativeToolsOnMachine Sets the native tools on machine environment variable (indicating that the script should use native tools on machine)" + Write-Host " -nodeReuse Sets nodereuse msbuild parameter ('true' or 'false')" + Write-Host " -buildCheck Sets /check msbuild parameter" + Write-Host " -fromVMR Set when building from within the VMR" Write-Host "" Write-Host "Command line arguments not listed above are passed thru to msbuild." @@ -97,6 +102,7 @@ function Build { $bl = if ($binaryLog) { '/bl:' + (Join-Path $LogDir 'Build.binlog') } else { '' } $platformArg = if ($platform) { "/p:Platform=$platform" } else { '' } + $check = if ($buildCheck) { '/check' } else { '' } if ($projects) { # Re-assign properties to a new variable because PowerShell doesn't let us append properties directly for unclear reasons. @@ -113,6 +119,7 @@ function Build { MSBuild $toolsetBuildProj ` $bl ` $platformArg ` + $check ` /p:Configuration=$configuration ` /p:RepoRoot=$RepoRoot ` /p:Restore=$restore ` @@ -122,11 +129,13 @@ function Build { /p:Deploy=$deploy ` /p:Test=$test ` /p:Pack=$pack ` - /p:DotNetBuildRepo=$productBuild ` + /p:DotNetBuild=$productBuild ` + /p:DotNetBuildFromVMR=$fromVMR ` /p:IntegrationTest=$integrationTest ` /p:PerformanceTest=$performanceTest ` /p:Sign=$sign ` /p:Publish=$publish ` + /p:RestoreStaticGraphEnableBinaryLogger=$binaryLog ` @properties } diff --git a/src/vstest/eng/common/build.sh b/src/vstest/eng/common/build.sh index ac1ee8620cd..9767bb411a4 100755 --- a/src/vstest/eng/common/build.sh +++ b/src/vstest/eng/common/build.sh @@ -42,6 +42,8 @@ usage() echo " --prepareMachine Prepare machine for CI run, clean up processes after build" echo " --nodeReuse Sets nodereuse msbuild parameter ('true' or 'false')" echo " --warnAsError Sets warnaserror msbuild parameter ('true' or 'false')" + echo " --buildCheck Sets /check msbuild parameter" + echo " --fromVMR Set when building from within the VMR" echo "" echo "Command line arguments not listed above are passed thru to msbuild." echo "Arguments can also be passed in with a single hyphen." @@ -63,6 +65,7 @@ restore=false build=false source_build=false product_build=false +from_vmr=false rebuild=false test=false integration_test=false @@ -76,6 +79,7 @@ clean=false warn_as_error=true node_reuse=true +build_check=false binary_log=false exclude_ci_binary_log=false pipelines_log=false @@ -87,7 +91,7 @@ verbosity='minimal' runtime_source_feed='' runtime_source_feed_key='' -properties='' +properties=() while [[ $# > 0 ]]; do opt="$(echo "${1/#--/-}" | tr "[:upper:]" "[:lower:]")" case "$opt" in @@ -127,19 +131,22 @@ while [[ $# > 0 ]]; do -pack) pack=true ;; - -sourcebuild|-sb) + -sourcebuild|-source-build|-sb) build=true source_build=true product_build=true restore=true pack=true ;; - -productBuild|-pb) + -productbuild|-product-build|-pb) build=true product_build=true restore=true pack=true ;; + -fromvmr|-from-vmr) + from_vmr=true + ;; -test|-t) test=true ;; @@ -173,6 +180,9 @@ while [[ $# > 0 ]]; do node_reuse=$2 shift ;; + -buildcheck) + build_check=true + ;; -runtimesourcefeed) runtime_source_feed=$2 shift @@ -182,7 +192,7 @@ while [[ $# > 0 ]]; do shift ;; *) - properties="$properties $1" + properties+=("$1") ;; esac @@ -216,7 +226,7 @@ function Build { InitializeCustomToolset if [[ ! -z "$projects" ]]; then - properties="$properties /p:Projects=$projects" + properties+=("/p:Projects=$projects") fi local bl="" @@ -224,15 +234,21 @@ function Build { bl="/bl:\"$log_dir/Build.binlog\"" fi + local check="" + if [[ "$build_check" == true ]]; then + check="/check" + fi + MSBuild $_InitializeToolset \ $bl \ + $check \ /p:Configuration=$configuration \ /p:RepoRoot="$repo_root" \ /p:Restore=$restore \ /p:Build=$build \ - /p:DotNetBuildRepo=$product_build \ - /p:ArcadeBuildFromSource=$source_build \ + /p:DotNetBuild=$product_build \ /p:DotNetBuildSourceOnly=$source_build \ + /p:DotNetBuildFromVMR=$from_vmr \ /p:Rebuild=$rebuild \ /p:Test=$test \ /p:Pack=$pack \ @@ -240,7 +256,8 @@ function Build { /p:PerformanceTest=$performance_test \ /p:Sign=$sign \ /p:Publish=$publish \ - $properties + /p:RestoreStaticGraphEnableBinaryLogger=$binary_log \ + ${properties[@]+"${properties[@]}"} ExitWithExitCode 0 } diff --git a/src/vstest/eng/common/cibuild.sh b/src/vstest/eng/common/cibuild.sh index 1a02c0dec8f..66e3b0ac61c 100644 --- a/src/vstest/eng/common/cibuild.sh +++ b/src/vstest/eng/common/cibuild.sh @@ -13,4 +13,4 @@ while [[ -h $source ]]; do done scriptroot="$( cd -P "$( dirname "$source" )" && pwd )" -. "$scriptroot/build.sh" --restore --build --test --pack --publish --ci $@ \ No newline at end of file +. "$scriptroot/build.sh" --restore --build --test --pack --publish --ci $@ diff --git a/src/vstest/eng/common/core-templates/job/job.yml b/src/vstest/eng/common/core-templates/job/job.yml index ba53ebfbd51..6badecba7bc 100644 --- a/src/vstest/eng/common/core-templates/job/job.yml +++ b/src/vstest/eng/common/core-templates/job/job.yml @@ -19,10 +19,10 @@ parameters: # publishing defaults artifacts: '' enableMicrobuild: false + enableMicrobuildForMacAndLinux: false enablePublishBuildArtifacts: false enablePublishBuildAssets: false enablePublishTestResults: false - enablePublishUsingPipelines: false enableBuildRetry: false mergeTestResults: false testRunTitle: '' @@ -73,9 +73,6 @@ jobs: - ${{ if ne(parameters.enableTelemetry, 'false') }}: - name: DOTNET_CLI_TELEMETRY_PROFILE value: '$(Build.Repository.Uri)' - - ${{ if eq(parameters.enableRichCodeNavigation, 'true') }}: - - name: EnableRichCodeNavigation - value: 'true' # Retry signature validation up to three times, waiting 2 seconds between attempts. # See https://learn.microsoft.com/en-us/nuget/reference/errors-and-warnings/nu3028#retry-untrusted-root-failures - name: NUGET_EXPERIMENTAL_CHAIN_BUILD_RETRY_POLICY @@ -127,18 +124,11 @@ jobs: - ${{ preStep }} - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: - - ${{ if eq(parameters.enableMicrobuild, 'true') }}: - - task: MicroBuildSigningPlugin@4 - displayName: Install MicroBuild plugin - inputs: - signType: $(_SignType) - zipSources: false - feedSource: https://dnceng.pkgs.visualstudio.com/_packaging/MicroBuildToolset/nuget/v3/index.json - env: - TeamName: $(_TeamName) - MicroBuildOutputFolderOverride: '$(Agent.TempDirectory)' + - template: /eng/common/core-templates/steps/install-microbuild.yml + parameters: + enableMicrobuild: ${{ parameters.enableMicrobuild }} + enableMicrobuildForMacAndLinux: ${{ parameters.enableMicrobuildForMacAndLinux }} continueOnError: ${{ parameters.continueOnError }} - condition: and(succeeded(), in(variables['_SignType'], 'real', 'test'), eq(variables['Agent.Os'], 'Windows_NT')) - ${{ if and(eq(parameters.runAsPublic, 'false'), eq(variables['System.TeamProject'], 'internal')) }}: - task: NuGetAuthenticate@1 @@ -154,27 +144,15 @@ jobs: - ${{ each step in parameters.steps }}: - ${{ step }} - - ${{ if eq(parameters.enableRichCodeNavigation, true) }}: - - task: RichCodeNavIndexer@0 - displayName: RichCodeNav Upload - inputs: - languages: ${{ coalesce(parameters.richCodeNavigationLanguage, 'csharp') }} - environment: ${{ coalesce(parameters.richCodeNavigationEnvironment, 'internal') }} - richNavLogOutputDirectory: $(Build.SourcesDirectory)/artifacts/bin - uploadRichNavArtifacts: ${{ coalesce(parameters.richCodeNavigationUploadArtifacts, false) }} - continueOnError: true - - ${{ each step in parameters.componentGovernanceSteps }}: - ${{ step }} - - ${{ if eq(parameters.enableMicrobuild, 'true') }}: - - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: - - task: MicroBuildCleanup@1 - displayName: Execute Microbuild cleanup tasks - condition: and(always(), in(variables['_SignType'], 'real', 'test'), eq(variables['Agent.Os'], 'Windows_NT')) + - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: + - template: /eng/common/core-templates/steps/cleanup-microbuild.yml + parameters: + enableMicrobuild: ${{ parameters.enableMicrobuild }} + enableMicrobuildForMacAndLinux: ${{ parameters.enableMicrobuildForMacAndLinux }} continueOnError: ${{ parameters.continueOnError }} - env: - TeamName: $(_TeamName) # Publish test results - ${{ if or(and(eq(parameters.enablePublishTestResults, 'true'), eq(parameters.testResultsFormat, '')), eq(parameters.testResultsFormat, 'xunit')) }}: diff --git a/src/vstest/eng/common/core-templates/job/onelocbuild.yml b/src/vstest/eng/common/core-templates/job/onelocbuild.yml index 00feec8ebbc..8034815f421 100644 --- a/src/vstest/eng/common/core-templates/job/onelocbuild.yml +++ b/src/vstest/eng/common/core-templates/job/onelocbuild.yml @@ -86,8 +86,7 @@ jobs: isAutoCompletePrSelected: ${{ parameters.AutoCompletePr }} ${{ if eq(parameters.CreatePr, true) }}: isUseLfLineEndingsSelected: ${{ parameters.UseLfLineEndings }} - ${{ if eq(parameters.RepoType, 'gitHub') }}: - isShouldReusePrSelected: ${{ parameters.ReusePr }} + isShouldReusePrSelected: ${{ parameters.ReusePr }} packageSourceAuth: patAuth patVariable: ${{ parameters.CeapexPat }} ${{ if eq(parameters.RepoType, 'gitHub') }}: @@ -118,4 +117,4 @@ jobs: pathToPublish: '$(Build.SourcesDirectory)/eng/Localize/' publishLocation: Container artifactName: Loc - condition: ${{ parameters.condition }} \ No newline at end of file + condition: ${{ parameters.condition }} diff --git a/src/vstest/eng/common/core-templates/job/publish-build-assets.yml b/src/vstest/eng/common/core-templates/job/publish-build-assets.yml index 3d3356e3196..d5303229c97 100644 --- a/src/vstest/eng/common/core-templates/job/publish-build-assets.yml +++ b/src/vstest/eng/common/core-templates/job/publish-build-assets.yml @@ -20,9 +20,6 @@ parameters: # if 'true', the build won't run any of the internal only steps, even if it is running in non-public projects. runAsPublic: false - # Optional: whether the build's artifacts will be published using release pipelines or direct feed publishing - publishUsingPipelines: false - # Optional: whether the build's artifacts will be published using release pipelines or direct feed publishing publishAssetsImmediately: false @@ -32,6 +29,15 @@ parameters: is1ESPipeline: '' + # Optional: 🌤️ or not the build has assets it wants to publish to BAR + isAssetlessBuild: false + + # Optional, publishing version + publishingVersion: 3 + + # Optional: A minimatch pattern for the asset manifests to publish to BAR + assetManifestsPattern: '*/manifests/**/*.xml' + jobs: - job: Asset_Registry_Publish @@ -75,15 +81,33 @@ jobs: - checkout: self fetchDepth: 3 clean: true - - - task: DownloadBuildArtifacts@0 - displayName: Download artifact - inputs: - artifactName: AssetManifests - downloadPath: '$(Build.StagingDirectory)/Download' - checkDownloadedFiles: true - condition: ${{ parameters.condition }} - continueOnError: ${{ parameters.continueOnError }} + + - ${{ if eq(parameters.isAssetlessBuild, 'false') }}: + - ${{ if eq(parameters.publishingVersion, 3) }}: + - task: DownloadPipelineArtifact@2 + displayName: Download Asset Manifests + inputs: + artifactName: AssetManifests + targetPath: '$(Build.StagingDirectory)/AssetManifests' + condition: ${{ parameters.condition }} + continueOnError: ${{ parameters.continueOnError }} + - ${{ if eq(parameters.publishingVersion, 4) }}: + - task: DownloadPipelineArtifact@2 + displayName: Download V4 asset manifests + inputs: + itemPattern: '*/manifests/**/*.xml' + targetPath: '$(Build.StagingDirectory)/AllAssetManifests' + condition: ${{ parameters.condition }} + continueOnError: ${{ parameters.continueOnError }} + - task: CopyFiles@2 + displayName: Copy V4 asset manifests to AssetManifests + inputs: + SourceFolder: '$(Build.StagingDirectory)/AllAssetManifests' + Contents: ${{ parameters.assetManifestsPattern }} + TargetFolder: '$(Build.StagingDirectory)/AssetManifests' + flattenFolders: true + condition: ${{ parameters.condition }} + continueOnError: ${{ parameters.continueOnError }} - task: NuGetAuthenticate@1 @@ -95,9 +119,9 @@ jobs: scriptLocation: scriptPath scriptPath: $(Build.SourcesDirectory)/eng/common/sdk-task.ps1 arguments: -task PublishBuildAssets -restore -msbuildEngine dotnet - /p:ManifestsPath='$(Build.StagingDirectory)/Download/AssetManifests' + /p:ManifestsPath='$(Build.StagingDirectory)/AssetManifests' + /p:IsAssetlessBuild=${{ parameters.isAssetlessBuild }} /p:MaestroApiEndpoint=https://maestro.dot.net - /p:PublishUsingPipelines=${{ parameters.publishUsingPipelines }} /p:OfficialBuildId=$(Build.BuildNumber) condition: ${{ parameters.condition }} continueOnError: ${{ parameters.continueOnError }} @@ -120,6 +144,17 @@ jobs: Copy-Item -Path $symbolExclusionfile -Destination "$(Build.StagingDirectory)/ReleaseConfigs" } + - ${{ if eq(parameters.publishingVersion, 4) }}: + - template: /eng/common/core-templates/steps/publish-pipeline-artifacts.yml + parameters: + is1ESPipeline: ${{ parameters.is1ESPipeline }} + args: + targetPath: '$(Build.ArtifactStagingDirectory)/MergedManifest.xml' + artifactName: AssetManifests + displayName: 'Publish Merged Manifest' + retryCountOnTaskFailure: 10 # for any logs being locked + sbomEnabled: false # we don't need SBOM for logs + - template: /eng/common/core-templates/steps/publish-build-artifacts.yml parameters: is1ESPipeline: ${{ parameters.is1ESPipeline }} @@ -129,7 +164,7 @@ jobs: publishLocation: Container artifactName: ReleaseConfigs - - ${{ if eq(parameters.publishAssetsImmediately, 'true') }}: + - ${{ if or(eq(parameters.publishAssetsImmediately, 'true'), eq(parameters.isAssetlessBuild, 'true')) }}: - template: /eng/common/core-templates/post-build/setup-maestro-vars.yml parameters: BARBuildId: ${{ parameters.BARBuildId }} @@ -150,6 +185,7 @@ jobs: -WaitPublishingFinish true -ArtifactsPublishingAdditionalParameters '${{ parameters.artifactsPublishingAdditionalParameters }}' -SymbolPublishingAdditionalParameters '${{ parameters.symbolPublishingAdditionalParameters }}' + -SkipAssetsPublishing '${{ parameters.isAssetlessBuild }}' - ${{ if eq(parameters.enablePublishBuildArtifacts, 'true') }}: - template: /eng/common/core-templates/steps/publish-logs.yml diff --git a/src/vstest/eng/common/core-templates/job/source-build.yml b/src/vstest/eng/common/core-templates/job/source-build.yml index d47f09d58fd..d805d5faeb9 100644 --- a/src/vstest/eng/common/core-templates/job/source-build.yml +++ b/src/vstest/eng/common/core-templates/job/source-build.yml @@ -12,9 +12,10 @@ parameters: # The name of the job. This is included in the job ID. # targetRID: '' # The name of the target RID to use, instead of the one auto-detected by Arcade. - # nonPortable: false + # portableBuild: false # Enables non-portable mode. This means a more specific RID (e.g. fedora.32-x64 rather than - # linux-x64), and compiling against distro-provided packages rather than portable ones. + # linux-x64), and compiling against distro-provided packages rather than portable ones. The + # default is portable mode. # skipPublishValidation: false # Disables publishing validation. By default, a check is performed to ensure no packages are # published by source-build. diff --git a/src/vstest/eng/common/core-templates/job/source-index-stage1.yml b/src/vstest/eng/common/core-templates/job/source-index-stage1.yml index 8b833332b3e..30530359a5d 100644 --- a/src/vstest/eng/common/core-templates/job/source-index-stage1.yml +++ b/src/vstest/eng/common/core-templates/job/source-index-stage1.yml @@ -1,8 +1,5 @@ parameters: runAsPublic: false - sourceIndexUploadPackageVersion: 2.0.0-20250425.2 - sourceIndexProcessBinlogPackageVersion: 1.0.1-20250425.2 - sourceIndexPackageSource: https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json sourceIndexBuildCommand: powershell -NoLogo -NoProfile -ExecutionPolicy Bypass -Command "eng/common/build.ps1 -restore -build -binarylog -ci" preSteps: [] binlogPath: artifacts/log/Debug/Build.binlog @@ -16,12 +13,6 @@ jobs: dependsOn: ${{ parameters.dependsOn }} condition: ${{ parameters.condition }} variables: - - name: SourceIndexUploadPackageVersion - value: ${{ parameters.sourceIndexUploadPackageVersion }} - - name: SourceIndexProcessBinlogPackageVersion - value: ${{ parameters.sourceIndexProcessBinlogPackageVersion }} - - name: SourceIndexPackageSource - value: ${{ parameters.sourceIndexPackageSource }} - name: BinlogPath value: ${{ parameters.binlogPath }} - template: /eng/common/core-templates/variables/pool-providers.yml @@ -34,12 +25,10 @@ jobs: pool: ${{ if eq(variables['System.TeamProject'], 'public') }}: name: $(DncEngPublicBuildPool) - image: 1es-windows-2022-open - os: windows + image: windows.vs2022.amd64.open ${{ if eq(variables['System.TeamProject'], 'internal') }}: name: $(DncEngInternalBuildPool) - image: 1es-windows-2022 - os: windows + image: windows.vs2022.amd64 steps: - ${{ if eq(parameters.is1ESPipeline, '') }}: @@ -47,35 +36,9 @@ jobs: - ${{ each preStep in parameters.preSteps }}: - ${{ preStep }} - - - task: UseDotNet@2 - displayName: Use .NET 8 SDK - inputs: - packageType: sdk - version: 8.0.x - installationPath: $(Agent.TempDirectory)/dotnet - workingDirectory: $(Agent.TempDirectory) - - - script: | - $(Agent.TempDirectory)/dotnet/dotnet tool install BinLogToSln --version $(sourceIndexProcessBinlogPackageVersion) --add-source $(SourceIndexPackageSource) --tool-path $(Agent.TempDirectory)/.source-index/tools - $(Agent.TempDirectory)/dotnet/dotnet tool install UploadIndexStage1 --version $(sourceIndexUploadPackageVersion) --add-source $(SourceIndexPackageSource) --tool-path $(Agent.TempDirectory)/.source-index/tools - displayName: Download Tools - # Set working directory to temp directory so 'dotnet' doesn't try to use global.json and use the repo's sdk. - workingDirectory: $(Agent.TempDirectory) - - script: ${{ parameters.sourceIndexBuildCommand }} displayName: Build Repository - - script: $(Agent.TempDirectory)/.source-index/tools/BinLogToSln -i $(BinlogPath) -r $(Build.SourcesDirectory) -n $(Build.Repository.Name) -o .source-index/stage1output - displayName: Process Binlog into indexable sln - - - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: - - task: AzureCLI@2 - displayName: Log in to Azure and upload stage1 artifacts to source index - inputs: - azureSubscription: 'SourceDotNet Stage1 Publish' - addSpnToEnvironment: true - scriptType: 'ps' - scriptLocation: 'inlineScript' - inlineScript: | - $(Agent.TempDirectory)/.source-index/tools/UploadIndexStage1 -i .source-index/stage1output -n $(Build.Repository.Name) -s netsourceindexstage1 -b stage1 + - template: /eng/common/core-templates/steps/source-index-stage1-publish.yml + parameters: + binLogPath: ${{ parameters.binLogPath }} \ No newline at end of file diff --git a/src/vstest/eng/common/core-templates/jobs/codeql-build.yml b/src/vstest/eng/common/core-templates/jobs/codeql-build.yml index f2144252cc6..693b00b3704 100644 --- a/src/vstest/eng/common/core-templates/jobs/codeql-build.yml +++ b/src/vstest/eng/common/core-templates/jobs/codeql-build.yml @@ -15,7 +15,6 @@ jobs: enablePublishBuildArtifacts: false enablePublishTestResults: false enablePublishBuildAssets: false - enablePublishUsingPipelines: false enableTelemetry: true variables: diff --git a/src/vstest/eng/common/core-templates/jobs/jobs.yml b/src/vstest/eng/common/core-templates/jobs/jobs.yml index ea69be4341c..bf35b78faa6 100644 --- a/src/vstest/eng/common/core-templates/jobs/jobs.yml +++ b/src/vstest/eng/common/core-templates/jobs/jobs.yml @@ -5,9 +5,6 @@ parameters: # Optional: Include PublishBuildArtifacts task enablePublishBuildArtifacts: false - # Optional: Enable publishing using release pipelines - enablePublishUsingPipelines: false - # Optional: Enable running the source-build jobs to build repo from source enableSourceBuild: false @@ -30,6 +27,9 @@ parameters: # Optional: Publish the assets as soon as the publish to BAR stage is complete, rather doing so in a separate stage. publishAssetsImmediately: false + # Optional: 🌤️ or not the build has assets it wants to publish to BAR + isAssetlessBuild: false + # Optional: If using publishAssetsImmediately and additional parameters are needed, can be used to send along additional parameters (normally sent to post-build.yml) artifactsPublishingAdditionalParameters: '' signingValidationAdditionalParameters: '' @@ -96,7 +96,7 @@ jobs: ${{ parameter.key }}: ${{ parameter.value }} - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: - - ${{ if or(eq(parameters.enablePublishBuildAssets, true), eq(parameters.artifacts.publish.manifests, 'true'), ne(parameters.artifacts.publish.manifests, '')) }}: + - ${{ if or(eq(parameters.enablePublishBuildAssets, true), eq(parameters.artifacts.publish.manifests, 'true'), ne(parameters.artifacts.publish.manifests, ''), eq(parameters.isAssetlessBuild, true)) }}: - template: ../job/publish-build-assets.yml parameters: is1ESPipeline: ${{ parameters.is1ESPipeline }} @@ -112,8 +112,8 @@ jobs: - Source_Build_Complete runAsPublic: ${{ parameters.runAsPublic }} - publishUsingPipelines: ${{ parameters.enablePublishUsingPipelines }} - publishAssetsImmediately: ${{ parameters.publishAssetsImmediately }} + publishAssetsImmediately: ${{ or(parameters.publishAssetsImmediately, parameters.isAssetlessBuild) }} + isAssetlessBuild: ${{ parameters.isAssetlessBuild }} enablePublishBuildArtifacts: ${{ parameters.enablePublishBuildArtifacts }} artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }} signingValidationAdditionalParameters: ${{ parameters.signingValidationAdditionalParameters }} diff --git a/src/vstest/eng/common/core-templates/jobs/source-build.yml b/src/vstest/eng/common/core-templates/jobs/source-build.yml index a10ccfbee6d..df24c948ba1 100644 --- a/src/vstest/eng/common/core-templates/jobs/source-build.yml +++ b/src/vstest/eng/common/core-templates/jobs/source-build.yml @@ -14,7 +14,7 @@ parameters: # This is the default platform provided by Arcade, intended for use by a managed-only repo. defaultManagedPlatform: name: 'Managed' - container: 'mcr.microsoft.com/dotnet-buildtools/prereqs:centos-stream9' + container: 'mcr.microsoft.com/dotnet-buildtools/prereqs:centos-stream-10-amd64' # Defines the platforms on which to run build jobs. One job is created for each platform, and the # object in this array is sent to the job template as 'platform'. If no platforms are specified, diff --git a/src/vstest/eng/common/core-templates/post-build/post-build.yml b/src/vstest/eng/common/core-templates/post-build/post-build.yml index a8c0bd3b921..a151fd811e3 100644 --- a/src/vstest/eng/common/core-templates/post-build/post-build.yml +++ b/src/vstest/eng/common/core-templates/post-build/post-build.yml @@ -60,6 +60,11 @@ parameters: artifactNames: '' downloadArtifacts: true + - name: isAssetlessBuild + type: boolean + displayName: Is Assetless Build + default: false + # These parameters let the user customize the call to sdk-task.ps1 for publishing # symbols & general artifacts as well as for signing validation - name: symbolPublishingAdditionalParameters @@ -188,9 +193,6 @@ stages: buildId: $(AzDOBuildId) artifactName: PackageArtifacts checkDownloadedFiles: true - itemPattern: | - ** - !**/Microsoft.SourceBuild.Intermediate.*.nupkg # This is necessary whenever we want to publish/restore to an AzDO private feed # Since sdk-task.ps1 tries to restore packages we need to do this authentication here @@ -320,3 +322,4 @@ stages: -RequireDefaultChannels ${{ parameters.requireDefaultChannels }} -ArtifactsPublishingAdditionalParameters '${{ parameters.artifactsPublishingAdditionalParameters }}' -SymbolPublishingAdditionalParameters '${{ parameters.symbolPublishingAdditionalParameters }}' + -SkipAssetsPublishing '${{ parameters.isAssetlessBuild }}' diff --git a/src/vstest/eng/common/core-templates/steps/cleanup-microbuild.yml b/src/vstest/eng/common/core-templates/steps/cleanup-microbuild.yml new file mode 100644 index 00000000000..c0fdcd3379d --- /dev/null +++ b/src/vstest/eng/common/core-templates/steps/cleanup-microbuild.yml @@ -0,0 +1,28 @@ +parameters: + # Enable cleanup tasks for MicroBuild + enableMicrobuild: false + # Enable cleanup tasks for MicroBuild on Mac and Linux + # Will be ignored if 'enableMicrobuild' is false or 'Agent.Os' is 'Windows_NT' + enableMicrobuildForMacAndLinux: false + continueOnError: false + +steps: + - ${{ if eq(parameters.enableMicrobuild, 'true') }}: + - task: MicroBuildCleanup@1 + displayName: Execute Microbuild cleanup tasks + condition: and( + always(), + or( + and( + eq(variables['Agent.Os'], 'Windows_NT'), + in(variables['_SignType'], 'real', 'test') + ), + and( + ${{ eq(parameters.enableMicrobuildForMacAndLinux, true) }}, + ne(variables['Agent.Os'], 'Windows_NT'), + eq(variables['_SignType'], 'real') + ) + )) + continueOnError: ${{ parameters.continueOnError }} + env: + TeamName: $(_TeamName) diff --git a/src/vstest/eng/common/core-templates/steps/generate-sbom.yml b/src/vstest/eng/common/core-templates/steps/generate-sbom.yml index 56a09009482..44a9636cdff 100644 --- a/src/vstest/eng/common/core-templates/steps/generate-sbom.yml +++ b/src/vstest/eng/common/core-templates/steps/generate-sbom.yml @@ -5,7 +5,7 @@ # IgnoreDirectories - Directories to ignore for SBOM generation. This will be passed through to the CG component detector. parameters: - PackageVersion: 9.0.0 + PackageVersion: 10.0.0 BuildDropPath: '$(Build.SourcesDirectory)/artifacts' PackageName: '.NET' ManifestDirPath: $(Build.ArtifactStagingDirectory)/sbom diff --git a/src/vstest/eng/common/core-templates/steps/get-delegation-sas.yml b/src/vstest/eng/common/core-templates/steps/get-delegation-sas.yml index 9db5617ea7d..d2901470a7f 100644 --- a/src/vstest/eng/common/core-templates/steps/get-delegation-sas.yml +++ b/src/vstest/eng/common/core-templates/steps/get-delegation-sas.yml @@ -31,16 +31,7 @@ steps: # Calculate the expiration of the SAS token and convert to UTC $expiry = (Get-Date).AddHours(${{ parameters.expiryInHours }}).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ") - # Temporarily work around a helix issue where SAS tokens with / in them will cause incorrect downloads - # of correlation payloads. https://github.com/dotnet/dnceng/issues/3484 - $sas = "" - do { - $sas = az storage container generate-sas --account-name ${{ parameters.storageAccount }} --name ${{ parameters.container }} --permissions ${{ parameters.permissions }} --expiry $expiry --auth-mode login --as-user -o tsv - if ($LASTEXITCODE -ne 0) { - Write-Error "Failed to generate SAS token." - exit 1 - } - } while($sas.IndexOf('/') -ne -1) + $sas = az storage container generate-sas --account-name ${{ parameters.storageAccount }} --name ${{ parameters.container }} --permissions ${{ parameters.permissions }} --expiry $expiry --auth-mode login --as-user -o tsv if ($LASTEXITCODE -ne 0) { Write-Error "Failed to generate SAS token." diff --git a/src/vstest/eng/common/core-templates/steps/install-microbuild.yml b/src/vstest/eng/common/core-templates/steps/install-microbuild.yml new file mode 100644 index 00000000000..f3064a7834e --- /dev/null +++ b/src/vstest/eng/common/core-templates/steps/install-microbuild.yml @@ -0,0 +1,54 @@ +parameters: + # Enable install tasks for MicroBuild + enableMicrobuild: false + # Enable install tasks for MicroBuild on Mac and Linux + # Will be ignored if 'enableMicrobuild' is false or 'Agent.Os' is 'Windows_NT' + enableMicrobuildForMacAndLinux: false + # Location of the MicroBuild output folder + microBuildOutputFolder: '$(Build.SourcesDirectory)' + continueOnError: false + +steps: + - ${{ if eq(parameters.enableMicrobuild, 'true') }}: + - ${{ if eq(parameters.enableMicrobuildForMacAndLinux, 'true') }}: + # Needed to download the MicroBuild plugin nupkgs on Mac and Linux when nuget.exe is unavailable + - task: UseDotNet@2 + displayName: Install .NET 8.0 SDK for MicroBuild Plugin + inputs: + packageType: sdk + version: 8.0.x + installationPath: ${{ parameters.microBuildOutputFolder }}/.dotnet + workingDirectory: ${{ parameters.microBuildOutputFolder }} + condition: and(succeeded(), ne(variables['Agent.Os'], 'Windows_NT')) + + - task: MicroBuildSigningPlugin@4 + displayName: Install MicroBuild plugin + inputs: + signType: $(_SignType) + zipSources: false + feedSource: https://dnceng.pkgs.visualstudio.com/_packaging/MicroBuildToolset/nuget/v3/index.json + ${{ if and(eq(parameters.enableMicrobuildForMacAndLinux, 'true'), ne(variables['Agent.Os'], 'Windows_NT')) }}: + azureSubscription: 'MicroBuild Signing Task (DevDiv)' + useEsrpCli: true + ${{ elseif eq(variables['System.TeamProject'], 'DevDiv') }}: + ConnectedPMEServiceName: 6cc74545-d7b9-4050-9dfa-ebefcc8961ea + ${{ else }}: + ConnectedPMEServiceName: 248d384a-b39b-46e3-8ad5-c2c210d5e7ca + env: + TeamName: $(_TeamName) + MicroBuildOutputFolderOverride: ${{ parameters.microBuildOutputFolder }} + SYSTEM_ACCESSTOKEN: $(System.AccessToken) + continueOnError: ${{ parameters.continueOnError }} + condition: and( + succeeded(), + or( + and( + eq(variables['Agent.Os'], 'Windows_NT'), + in(variables['_SignType'], 'real', 'test') + ), + and( + ${{ eq(parameters.enableMicrobuildForMacAndLinux, true) }}, + ne(variables['Agent.Os'], 'Windows_NT'), + eq(variables['_SignType'], 'real') + ) + )) diff --git a/src/vstest/eng/common/core-templates/steps/publish-logs.yml b/src/vstest/eng/common/core-templates/steps/publish-logs.yml index 80788c52319..de24d0087c5 100644 --- a/src/vstest/eng/common/core-templates/steps/publish-logs.yml +++ b/src/vstest/eng/common/core-templates/steps/publish-logs.yml @@ -34,7 +34,9 @@ steps: '$(akams-client-id)' '$(microsoft-symbol-server-pat)' '$(symweb-symbol-server-pat)' + '$(dnceng-symbol-server-pat)' '$(dn-bot-all-orgs-build-rw-code-rw)' + '$(System.AccessToken)' ${{parameters.CustomSensitiveDataList}} continueOnError: true condition: always() @@ -45,6 +47,7 @@ steps: SourceFolder: '$(Build.SourcesDirectory)/PostBuildLogs' Contents: '**' TargetFolder: '$(Build.ArtifactStagingDirectory)/PostBuildLogs' + condition: always() - template: /eng/common/core-templates/steps/publish-build-artifacts.yml parameters: diff --git a/src/vstest/eng/common/core-templates/steps/source-build.yml b/src/vstest/eng/common/core-templates/steps/source-build.yml index 37133b55b75..acf16ed3496 100644 --- a/src/vstest/eng/common/core-templates/steps/source-build.yml +++ b/src/vstest/eng/common/core-templates/steps/source-build.yml @@ -19,25 +19,12 @@ steps: set -x df -h - # If file changes are detected, set CopyWipIntoInnerSourceBuildRepo to copy the WIP changes into the inner source build repo. - internalRestoreArgs= - if ! git diff --quiet; then - internalRestoreArgs='/p:CopyWipIntoInnerSourceBuildRepo=true' - # The 'Copy WIP' feature of source build uses git stash to apply changes from the original repo. - # This only works if there is a username/email configured, which won't be the case in most CI runs. - git config --get user.email - if [ $? -ne 0 ]; then - git config user.email dn-bot@microsoft.com - git config user.name dn-bot - fi - fi - # If building on the internal project, the internal storage variable may be available (usually only if needed) # In that case, add variables to allow the download of internal runtimes if the specified versions are not found # in the default public locations. internalRuntimeDownloadArgs= if [ '$(dotnetbuilds-internal-container-read-token-base64)' != '$''(dotnetbuilds-internal-container-read-token-base64)' ]; then - internalRuntimeDownloadArgs='/p:DotNetRuntimeSourceFeed=https://dotnetbuilds.blob.core.windows.net/internal /p:DotNetRuntimeSourceFeedKey=$(dotnetbuilds-internal-container-read-token-base64) --runtimesourcefeed https://dotnetbuilds.blob.core.windows.net/internal --runtimesourcefeedkey $(dotnetbuilds-internal-container-read-token-base64)' + internalRuntimeDownloadArgs='/p:DotNetRuntimeSourceFeed=https://ci.dot.net/internal /p:DotNetRuntimeSourceFeedKey=$(dotnetbuilds-internal-container-read-token-base64) --runtimesourcefeed https://ci.dot.net/internal --runtimesourcefeedkey $(dotnetbuilds-internal-container-read-token-base64)' fi buildConfig=Release @@ -46,85 +33,33 @@ steps: buildConfig='$(_BuildConfig)' fi - officialBuildArgs= - if [ '${{ and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}' = 'True' ]; then - officialBuildArgs='/p:DotNetPublishUsingPipelines=true /p:OfficialBuildId=$(BUILD.BUILDNUMBER)' - fi - targetRidArgs= if [ '${{ parameters.platform.targetRID }}' != '' ]; then targetRidArgs='/p:TargetRid=${{ parameters.platform.targetRID }}' fi - runtimeOsArgs= - if [ '${{ parameters.platform.runtimeOS }}' != '' ]; then - runtimeOsArgs='/p:RuntimeOS=${{ parameters.platform.runtimeOS }}' - fi - - baseOsArgs= - if [ '${{ parameters.platform.baseOS }}' != '' ]; then - baseOsArgs='/p:BaseOS=${{ parameters.platform.baseOS }}' - fi - - publishArgs= - if [ '${{ parameters.platform.skipPublishValidation }}' != 'true' ]; then - publishArgs='--publish' - fi - - assetManifestFileName=SourceBuild_RidSpecific.xml - if [ '${{ parameters.platform.name }}' != '' ]; then - assetManifestFileName=SourceBuild_${{ parameters.platform.name }}.xml + portableBuildArgs= + if [ '${{ parameters.platform.portableBuild }}' != '' ]; then + portableBuildArgs='/p:PortableBuild=${{ parameters.platform.portableBuild }}' fi ${{ coalesce(parameters.platform.buildScript, './build.sh') }} --ci \ --configuration $buildConfig \ - --restore --build --pack $publishArgs -bl \ + --restore --build --pack -bl \ + --source-build \ ${{ parameters.platform.buildArguments }} \ - $officialBuildArgs \ $internalRuntimeDownloadArgs \ - $internalRestoreArgs \ $targetRidArgs \ - $runtimeOsArgs \ - $baseOsArgs \ - /p:SourceBuildNonPortable=${{ parameters.platform.nonPortable }} \ - /p:ArcadeBuildFromSource=true \ - /p:DotNetBuildSourceOnly=true \ - /p:DotNetBuildRepo=true \ - /p:AssetManifestFileName=$assetManifestFileName + $portableBuildArgs \ displayName: Build -# Upload build logs for diagnosis. -- task: CopyFiles@2 - displayName: Prepare BuildLogs staging directory - inputs: - SourceFolder: '$(Build.SourcesDirectory)' - Contents: | - **/*.log - **/*.binlog - artifacts/sb/prebuilt-report/** - TargetFolder: '$(Build.StagingDirectory)/BuildLogs' - CleanTargetFolder: true - continueOnError: true - condition: succeededOrFailed() - - template: /eng/common/core-templates/steps/publish-pipeline-artifacts.yml parameters: is1ESPipeline: ${{ parameters.is1ESPipeline }} args: displayName: Publish BuildLogs - targetPath: '$(Build.StagingDirectory)/BuildLogs' + targetPath: artifacts/log/${{ coalesce(variables._BuildConfig, 'Release') }} artifactName: BuildLogs_SourceBuild_${{ parameters.platform.name }}_Attempt$(System.JobAttempt) continueOnError: true condition: succeededOrFailed() sbomEnabled: false # we don't need SBOM for logs - -# Manually inject component detection so that we can ignore the source build upstream cache, which contains -# a nupkg cache of input packages (a local feed). -# This path must match the upstream cache path in property 'CurrentRepoSourceBuiltNupkgCacheDir' -# in src\Microsoft.DotNet.Arcade.Sdk\tools\SourceBuild\SourceBuildArcade.targets -- template: /eng/common/core-templates/steps/component-governance.yml - parameters: - displayName: Component Detection (Exclude upstream cache) - is1ESPipeline: ${{ parameters.is1ESPipeline }} - componentGovernanceIgnoreDirectories: '$(Build.SourcesDirectory)/artifacts/sb/src/artifacts/obj/source-built-upstream-cache' - disableComponentGovernance: ${{ eq(variables['System.TeamProject'], 'public') }} diff --git a/src/vstest/eng/common/core-templates/steps/source-index-stage1-publish.yml b/src/vstest/eng/common/core-templates/steps/source-index-stage1-publish.yml new file mode 100644 index 00000000000..c2917c1efc1 --- /dev/null +++ b/src/vstest/eng/common/core-templates/steps/source-index-stage1-publish.yml @@ -0,0 +1,35 @@ +parameters: + sourceIndexUploadPackageVersion: 2.0.0-20250425.2 + sourceIndexProcessBinlogPackageVersion: 1.0.1-20250515.1 + sourceIndexPackageSource: https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json + binlogPath: artifacts/log/Debug/Build.binlog + +steps: +- task: UseDotNet@2 + displayName: "Source Index: Use .NET 9 SDK" + inputs: + packageType: sdk + version: 9.0.x + installationPath: $(Agent.TempDirectory)/dotnet + workingDirectory: $(Agent.TempDirectory) + +- script: | + $(Agent.TempDirectory)/dotnet/dotnet tool install BinLogToSln --version ${{parameters.sourceIndexProcessBinlogPackageVersion}} --add-source ${{parameters.SourceIndexPackageSource}} --tool-path $(Agent.TempDirectory)/.source-index/tools + $(Agent.TempDirectory)/dotnet/dotnet tool install UploadIndexStage1 --version ${{parameters.sourceIndexUploadPackageVersion}} --add-source ${{parameters.SourceIndexPackageSource}} --tool-path $(Agent.TempDirectory)/.source-index/tools + displayName: "Source Index: Download netsourceindex Tools" + # Set working directory to temp directory so 'dotnet' doesn't try to use global.json and use the repo's sdk. + workingDirectory: $(Agent.TempDirectory) + +- script: $(Agent.TempDirectory)/.source-index/tools/BinLogToSln -i ${{parameters.BinlogPath}} -r $(Build.SourcesDirectory) -n $(Build.Repository.Name) -o .source-index/stage1output + displayName: "Source Index: Process Binlog into indexable sln" + +- ${{ if and(ne(parameters.runAsPublic, 'true'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: + - task: AzureCLI@2 + displayName: "Source Index: Upload Source Index stage1 artifacts to Azure" + inputs: + azureSubscription: 'SourceDotNet Stage1 Publish' + addSpnToEnvironment: true + scriptType: 'ps' + scriptLocation: 'inlineScript' + inlineScript: | + $(Agent.TempDirectory)/.source-index/tools/UploadIndexStage1 -i .source-index/stage1output -n $(Build.Repository.Name) -s netsourceindexstage1 -b stage1 diff --git a/src/vstest/eng/common/cross/arm64/tizen/tizen.patch b/src/vstest/eng/common/cross/arm64/tizen/tizen.patch index af7c8be0590..2cebc547382 100644 --- a/src/vstest/eng/common/cross/arm64/tizen/tizen.patch +++ b/src/vstest/eng/common/cross/arm64/tizen/tizen.patch @@ -5,5 +5,5 @@ diff -u -r a/usr/lib/libc.so b/usr/lib/libc.so Use the shared library, but some functions are only in the static library, so try that secondarily. */ OUTPUT_FORMAT(elf64-littleaarch64) --GROUP ( /lib64/libc.so.6 /usr/lib64/libc_nonshared.a AS_NEEDED ( /lib/ld-linux-aarch64.so.1 ) ) +-GROUP ( /lib64/libc.so.6 /usr/lib64/libc_nonshared.a AS_NEEDED ( /lib64/ld-linux-aarch64.so.1 ) ) +GROUP ( libc.so.6 libc_nonshared.a AS_NEEDED ( ld-linux-aarch64.so.1 ) ) diff --git a/src/vstest/eng/common/cross/armel/armel.jessie.patch b/src/vstest/eng/common/cross/armel/armel.jessie.patch deleted file mode 100644 index 2d261561935..00000000000 --- a/src/vstest/eng/common/cross/armel/armel.jessie.patch +++ /dev/null @@ -1,43 +0,0 @@ -diff -u -r a/usr/include/urcu/uatomic/generic.h b/usr/include/urcu/uatomic/generic.h ---- a/usr/include/urcu/uatomic/generic.h 2014-10-22 15:00:58.000000000 -0700 -+++ b/usr/include/urcu/uatomic/generic.h 2020-10-30 21:38:28.550000000 -0700 -@@ -69,10 +69,10 @@ - #endif - #ifdef UATOMIC_HAS_ATOMIC_SHORT - case 2: -- return __sync_val_compare_and_swap_2(addr, old, _new); -+ return __sync_val_compare_and_swap_2((uint16_t*) addr, old, _new); - #endif - case 4: -- return __sync_val_compare_and_swap_4(addr, old, _new); -+ return __sync_val_compare_and_swap_4((uint32_t*) addr, old, _new); - #if (CAA_BITS_PER_LONG == 64) - case 8: - return __sync_val_compare_and_swap_8(addr, old, _new); -@@ -109,7 +109,7 @@ - return; - #endif - case 4: -- __sync_and_and_fetch_4(addr, val); -+ __sync_and_and_fetch_4((uint32_t*) addr, val); - return; - #if (CAA_BITS_PER_LONG == 64) - case 8: -@@ -148,7 +148,7 @@ - return; - #endif - case 4: -- __sync_or_and_fetch_4(addr, val); -+ __sync_or_and_fetch_4((uint32_t*) addr, val); - return; - #if (CAA_BITS_PER_LONG == 64) - case 8: -@@ -187,7 +187,7 @@ - return __sync_add_and_fetch_2(addr, val); - #endif - case 4: -- return __sync_add_and_fetch_4(addr, val); -+ return __sync_add_and_fetch_4((uint32_t*) addr, val); - #if (CAA_BITS_PER_LONG == 64) - case 8: - return __sync_add_and_fetch_8(addr, val); diff --git a/src/vstest/eng/common/cross/build-android-rootfs.sh b/src/vstest/eng/common/cross/build-android-rootfs.sh index 7e9ba2b75ed..fbd8d80848a 100644 --- a/src/vstest/eng/common/cross/build-android-rootfs.sh +++ b/src/vstest/eng/common/cross/build-android-rootfs.sh @@ -6,10 +6,11 @@ usage() { echo "Creates a toolchain and sysroot used for cross-compiling for Android." echo - echo "Usage: $0 [BuildArch] [ApiLevel]" + echo "Usage: $0 [BuildArch] [ApiLevel] [--ndk NDKVersion]" echo echo "BuildArch is the target architecture of Android. Currently only arm64 is supported." echo "ApiLevel is the target Android API level. API levels usually match to Android releases. See https://source.android.com/source/build-numbers.html" + echo "NDKVersion is the version of Android NDK. The default is r21. See https://developer.android.com/ndk/downloads/revision_history" echo echo "By default, the toolchain and sysroot will be generated in cross/android-rootfs/toolchain/[BuildArch]. You can change this behavior" echo "by setting the TOOLCHAIN_DIR environment variable" @@ -25,10 +26,15 @@ __BuildArch=arm64 __AndroidArch=aarch64 __AndroidToolchain=aarch64-linux-android -for i in "$@" - do - lowerI="$(echo $i | tr "[:upper:]" "[:lower:]")" - case $lowerI in +while :; do + if [[ "$#" -le 0 ]]; then + break + fi + + i=$1 + + lowerI="$(echo $i | tr "[:upper:]" "[:lower:]")" + case $lowerI in -?|-h|--help) usage exit 1 @@ -43,6 +49,10 @@ for i in "$@" __AndroidArch=arm __AndroidToolchain=arm-linux-androideabi ;; + --ndk) + shift + __NDK_Version=$1 + ;; *[0-9]) __ApiLevel=$i ;; @@ -50,8 +60,17 @@ for i in "$@" __UnprocessedBuildArgs="$__UnprocessedBuildArgs $i" ;; esac + shift done +if [[ "$__NDK_Version" == "r21" ]] || [[ "$__NDK_Version" == "r22" ]]; then + __NDK_File_Arch_Spec=-x86_64 + __SysRoot=sysroot +else + __NDK_File_Arch_Spec= + __SysRoot=toolchains/llvm/prebuilt/linux-x86_64/sysroot +fi + # Obtain the location of the bash script to figure out where the root of the repo is. __ScriptBaseDir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" @@ -78,6 +97,7 @@ fi echo "Target API level: $__ApiLevel" echo "Target architecture: $__BuildArch" +echo "NDK version: $__NDK_Version" echo "NDK location: $__NDK_Dir" echo "Target Toolchain location: $__ToolchainDir" @@ -85,8 +105,8 @@ echo "Target Toolchain location: $__ToolchainDir" if [ ! -d $__NDK_Dir ]; then echo Downloading the NDK into $__NDK_Dir mkdir -p $__NDK_Dir - wget -q --progress=bar:force:noscroll --show-progress https://dl.google.com/android/repository/android-ndk-$__NDK_Version-linux-x86_64.zip -O $__CrossDir/android-ndk-$__NDK_Version-linux-x86_64.zip - unzip -q $__CrossDir/android-ndk-$__NDK_Version-linux-x86_64.zip -d $__CrossDir + wget -q --progress=bar:force:noscroll --show-progress https://dl.google.com/android/repository/android-ndk-$__NDK_Version-linux$__NDK_File_Arch_Spec.zip -O $__CrossDir/android-ndk-$__NDK_Version-linux.zip + unzip -q $__CrossDir/android-ndk-$__NDK_Version-linux.zip -d $__CrossDir fi if [ ! -d $__lldb_Dir ]; then @@ -116,16 +136,11 @@ for path in $(wget -qO- https://packages.termux.dev/termux-main-21/dists/stable/ fi done -cp -R "$__TmpDir/data/data/com.termux/files/usr/"* "$__ToolchainDir/sysroot/usr/" +cp -R "$__TmpDir/data/data/com.termux/files/usr/"* "$__ToolchainDir/$__SysRoot/usr/" # Generate platform file for build.sh script to assign to __DistroRid echo "Generating platform file..." -echo "RID=android.${__ApiLevel}-${__BuildArch}" > $__ToolchainDir/sysroot/android_platform - -echo "Now to build coreclr, libraries and installers; run:" -echo ROOTFS_DIR=\$\(realpath $__ToolchainDir/sysroot\) ./build.sh --cross --arch $__BuildArch \ - --subsetCategory coreclr -echo ROOTFS_DIR=\$\(realpath $__ToolchainDir/sysroot\) ./build.sh --cross --arch $__BuildArch \ - --subsetCategory libraries -echo ROOTFS_DIR=\$\(realpath $__ToolchainDir/sysroot\) ./build.sh --cross --arch $__BuildArch \ - --subsetCategory installer +echo "RID=android.${__ApiLevel}-${__BuildArch}" > $__ToolchainDir/$__SysRoot/android_platform + +echo "Now to build coreclr, libraries and host; run:" +echo ROOTFS_DIR=$(realpath $__ToolchainDir/$__SysRoot) ./build.sh clr+libs+host --cross --arch $__BuildArch diff --git a/src/vstest/eng/common/cross/build-rootfs.sh b/src/vstest/eng/common/cross/build-rootfs.sh index 4b5e8d7166b..8abfb71f727 100644 --- a/src/vstest/eng/common/cross/build-rootfs.sh +++ b/src/vstest/eng/common/cross/build-rootfs.sh @@ -5,7 +5,7 @@ set -e usage() { echo "Usage: $0 [BuildArch] [CodeName] [lldbx.y] [llvmx[.y]] [--skipunmount] --rootfsdir ]" - echo "BuildArch can be: arm(default), arm64, armel, armv6, ppc64le, riscv64, s390x, x64, x86" + echo "BuildArch can be: arm(default), arm64, armel, armv6, loongarch64, ppc64le, riscv64, s390x, x64, x86" echo "CodeName - optional, Code name for Linux, can be: xenial(default), zesty, bionic, alpine" echo " for alpine can be specified with version: alpineX.YY or alpineedge" echo " for FreeBSD can be: freebsd13, freebsd14" @@ -15,6 +15,7 @@ usage() echo "llvmx[.y] - optional, LLVM version for LLVM related packages." echo "--skipunmount - optional, will skip the unmount of rootfs folder." echo "--skipsigcheck - optional, will skip package signature checks (allowing untrusted packages)." + echo "--skipemulation - optional, will skip qemu and debootstrap requirement when building environment for debian based systems." echo "--use-mirror - optional, use mirror URL to fetch resources, when available." echo "--jobs N - optional, restrict to N jobs." exit 1 @@ -52,28 +53,27 @@ __UbuntuPackages+=" symlinks" __UbuntuPackages+=" libicu-dev" __UbuntuPackages+=" liblttng-ust-dev" __UbuntuPackages+=" libunwind8-dev" -__UbuntuPackages+=" libnuma-dev" __AlpinePackages+=" gettext-dev" __AlpinePackages+=" icu-dev" __AlpinePackages+=" libunwind-dev" __AlpinePackages+=" lttng-ust-dev" __AlpinePackages+=" compiler-rt" -__AlpinePackages+=" numactl-dev" # runtime libraries' dependencies __UbuntuPackages+=" libcurl4-openssl-dev" __UbuntuPackages+=" libkrb5-dev" __UbuntuPackages+=" libssl-dev" __UbuntuPackages+=" zlib1g-dev" +__UbuntuPackages+=" libbrotli-dev" __AlpinePackages+=" curl-dev" __AlpinePackages+=" krb5-dev" __AlpinePackages+=" openssl-dev" __AlpinePackages+=" zlib-dev" -__FreeBSDBase="13.3-RELEASE" -__FreeBSDPkg="1.17.0" +__FreeBSDBase="13.4-RELEASE" +__FreeBSDPkg="1.21.3" __FreeBSDABI="13" __FreeBSDPackages="libunwind" __FreeBSDPackages+=" icu" @@ -91,18 +91,18 @@ __HaikuPackages="gcc_syslibs" __HaikuPackages+=" gcc_syslibs_devel" __HaikuPackages+=" gmp" __HaikuPackages+=" gmp_devel" -__HaikuPackages+=" icu66" -__HaikuPackages+=" icu66_devel" +__HaikuPackages+=" icu[0-9]+" +__HaikuPackages+=" icu[0-9]*_devel" __HaikuPackages+=" krb5" __HaikuPackages+=" krb5_devel" __HaikuPackages+=" libiconv" __HaikuPackages+=" libiconv_devel" -__HaikuPackages+=" llvm12_libunwind" -__HaikuPackages+=" llvm12_libunwind_devel" +__HaikuPackages+=" llvm[0-9]*_libunwind" +__HaikuPackages+=" llvm[0-9]*_libunwind_devel" __HaikuPackages+=" mpfr" __HaikuPackages+=" mpfr_devel" -__HaikuPackages+=" openssl" -__HaikuPackages+=" openssl_devel" +__HaikuPackages+=" openssl3" +__HaikuPackages+=" openssl3_devel" __HaikuPackages+=" zlib" __HaikuPackages+=" zlib_devel" @@ -128,10 +128,12 @@ __AlpineKeys=' 616adfeb:MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAq0BFD1D4lIxQcsqEpQzU\npNCYM3aP1V/fxxVdT4DWvSI53JHTwHQamKdMWtEXetWVbP5zSROniYKFXd/xrD9X\n0jiGHey3lEtylXRIPxe5s+wXoCmNLcJVnvTcDtwx/ne2NLHxp76lyc25At+6RgE6\nADjLVuoD7M4IFDkAsd8UQ8zM0Dww9SylIk/wgV3ZkifecvgUQRagrNUdUjR56EBZ\nraQrev4hhzOgwelT0kXCu3snbUuNY/lU53CoTzfBJ5UfEJ5pMw1ij6X0r5S9IVsy\nKLWH1hiO0NzU2c8ViUYCly4Fe9xMTFc6u2dy/dxf6FwERfGzETQxqZvSfrRX+GLj\n/QZAXiPg5178hT/m0Y3z5IGenIC/80Z9NCi+byF1WuJlzKjDcF/TU72zk0+PNM/H\nKuppf3JT4DyjiVzNC5YoWJT2QRMS9KLP5iKCSThwVceEEg5HfhQBRT9M6KIcFLSs\nmFjx9kNEEmc1E8hl5IR3+3Ry8G5/bTIIruz14jgeY9u5jhL8Vyyvo41jgt9sLHR1\n/J1TxKfkgksYev7PoX6/ZzJ1ksWKZY5NFoDXTNYUgzFUTOoEaOg3BAQKadb3Qbbq\nXIrxmPBdgrn9QI7NCgfnAY3Tb4EEjs3ON/BNyEhUENcXOH6I1NbcuBQ7g9P73kE4\nVORdoc8MdJ5eoKBpO8Ww8HECAwEAAQ== 616ae350:MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAyduVzi1mWm+lYo2Tqt/0\nXkCIWrDNP1QBMVPrE0/ZlU2bCGSoo2Z9FHQKz/mTyMRlhNqTfhJ5qU3U9XlyGOPJ\npiM+b91g26pnpXJ2Q2kOypSgOMOPA4cQ42PkHBEqhuzssfj9t7x47ppS94bboh46\nxLSDRff/NAbtwTpvhStV3URYkxFG++cKGGa5MPXBrxIp+iZf9GnuxVdST5PGiVGP\nODL/b69sPJQNbJHVquqUTOh5Ry8uuD2WZuXfKf7/C0jC/ie9m2+0CttNu9tMciGM\nEyKG1/Xhk5iIWO43m4SrrT2WkFlcZ1z2JSf9Pjm4C2+HovYpihwwdM/OdP8Xmsnr\nDzVB4YvQiW+IHBjStHVuyiZWc+JsgEPJzisNY0Wyc/kNyNtqVKpX6dRhMLanLmy+\nf53cCSI05KPQAcGj6tdL+D60uKDkt+FsDa0BTAobZ31OsFVid0vCXtsbplNhW1IF\nHwsGXBTVcfXg44RLyL8Lk/2dQxDHNHzAUslJXzPxaHBLmt++2COa2EI1iWlvtznk\nOk9WP8SOAIj+xdqoiHcC4j72BOVVgiITIJNHrbppZCq6qPR+fgXmXa+sDcGh30m6\n9Wpbr28kLMSHiENCWTdsFij+NQTd5S47H7XTROHnalYDuF1RpS+DpQidT5tUimaT\nJZDr++FjKrnnijbyNF8b98UCAwEAAQ== 616db30d:MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAnpUpyWDWjlUk3smlWeA0\nlIMW+oJ38t92CRLHH3IqRhyECBRW0d0aRGtq7TY8PmxjjvBZrxTNDpJT6KUk4LRm\na6A6IuAI7QnNK8SJqM0DLzlpygd7GJf8ZL9SoHSH+gFsYF67Cpooz/YDqWrlN7Vw\ntO00s0B+eXy+PCXYU7VSfuWFGK8TGEv6HfGMALLjhqMManyvfp8hz3ubN1rK3c8C\nUS/ilRh1qckdbtPvoDPhSbTDmfU1g/EfRSIEXBrIMLg9ka/XB9PvWRrekrppnQzP\nhP9YE3x/wbFc5QqQWiRCYyQl/rgIMOXvIxhkfe8H5n1Et4VAorkpEAXdsfN8KSVv\nLSMazVlLp9GYq5SUpqYX3KnxdWBgN7BJoZ4sltsTpHQ/34SXWfu3UmyUveWj7wp0\nx9hwsPirVI00EEea9AbP7NM2rAyu6ukcm4m6ATd2DZJIViq2es6m60AE6SMCmrQF\nwmk4H/kdQgeAELVfGOm2VyJ3z69fQuywz7xu27S6zTKi05Qlnohxol4wVb6OB7qG\nLPRtK9ObgzRo/OPumyXqlzAi/Yvyd1ZQk8labZps3e16bQp8+pVPiumWioMFJDWV\nGZjCmyMSU8V6MB6njbgLHoyg2LCukCAeSjbPGGGYhnKLm1AKSoJh3IpZuqcKCk5C\n8CM1S15HxV78s9dFntEqIokCAwEAAQ== +66ba20fe:MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAtfB12w4ZgqsXWZDfUAV/\n6Y4aHUKIu3q4SXrNZ7CXF9nXoAVYrS7NAxJdAodsY3vPCN0g5O8DFXR+390LdOuQ\n+HsGKCc1k5tX5ZXld37EZNTNSbR0k+NKhd9h6X3u6wqPOx7SIKxwAQR8qeeFq4pP\nrt9GAGlxtuYgzIIcKJPwE0dZlcBCg+GnptCUZXp/38BP1eYC+xTXSL6Muq1etYfg\nodXdb7Yl+2h1IHuOwo5rjgY5kpY7GcAs8AjGk3lDD/av60OTYccknH0NCVSmPoXK\nvrxDBOn0LQRNBLcAfnTKgHrzy0Q5h4TNkkyTgxkoQw5ObDk9nnabTxql732yy9BY\ns+hM9+dSFO1HKeVXreYSA2n1ndF18YAvAumzgyqzB7I4pMHXq1kC/8bONMJxwSkS\nYm6CoXKyavp7RqGMyeVpRC7tV+blkrrUml0BwNkxE+XnwDRB3xDV6hqgWe0XrifD\nYTfvd9ScZQP83ip0r4IKlq4GMv/R5shcCRJSkSZ6QSGshH40JYSoiwJf5FHbj9ND\n7do0UAqebWo4yNx63j/wb2ULorW3AClv0BCFSdPsIrCStiGdpgJDBR2P2NZOCob3\nG9uMj+wJD6JJg2nWqNJxkANXX37Qf8plgzssrhrgOvB0fjjS7GYhfkfmZTJ0wPOw\nA8+KzFseBh4UFGgue78KwgkCAwEAAQ== ' __Keyring= __KeyringFile="/usr/share/keyrings/ubuntu-archive-keyring.gpg" __SkipSigCheck=0 +__SkipEmulation=0 __UseMirror=0 __UnprocessedBuildArgs= @@ -162,9 +164,13 @@ while :; do armel) __BuildArch=armel __UbuntuArch=armel - __UbuntuRepo="http://ftp.debian.org/debian/" - __CodeName=jessie + __UbuntuRepo="http://archive.debian.org/debian/" + __CodeName=buster __KeyringFile="/usr/share/keyrings/debian-archive-keyring.gpg" + __LLDB_Package="liblldb-6.0-dev" + __UbuntuPackages="${__UbuntuPackages// libomp-dev/}" + __UbuntuPackages="${__UbuntuPackages// libomp5/}" + __UbuntuSuites= ;; armv6) __BuildArch=armv6 @@ -180,6 +186,18 @@ while :; do __Keyring="--keyring $__KeyringFile" fi ;; + loongarch64) + __BuildArch=loongarch64 + __AlpineArch=loongarch64 + __QEMUArch=loongarch64 + __UbuntuArch=loong64 + __UbuntuSuites=unreleased + __LLDB_Package="liblldb-19-dev" + + if [[ "$__CodeName" == "sid" ]]; then + __UbuntuRepo="http://ftp.ports.debian.org/debian-ports/" + fi + ;; riscv64) __BuildArch=riscv64 __AlpineArch=riscv64 @@ -264,44 +282,21 @@ while :; do ;; xenial) # Ubuntu 16.04 - if [[ "$__CodeName" != "jessie" ]]; then - __CodeName=xenial - fi - ;; - zesty) # Ubuntu 17.04 - if [[ "$__CodeName" != "jessie" ]]; then - __CodeName=zesty - fi + __CodeName=xenial ;; bionic) # Ubuntu 18.04 - if [[ "$__CodeName" != "jessie" ]]; then - __CodeName=bionic - fi + __CodeName=bionic ;; focal) # Ubuntu 20.04 - if [[ "$__CodeName" != "jessie" ]]; then - __CodeName=focal - fi + __CodeName=focal ;; jammy) # Ubuntu 22.04 - if [[ "$__CodeName" != "jessie" ]]; then - __CodeName=jammy - fi + __CodeName=jammy ;; noble) # Ubuntu 24.04 - if [[ "$__CodeName" != "jessie" ]]; then - __CodeName=noble - fi - if [[ -n "$__LLDB_Package" ]]; then - __LLDB_Package="liblldb-18-dev" - fi - ;; - jessie) # Debian 8 - __CodeName=jessie - __KeyringFile="/usr/share/keyrings/debian-archive-keyring.gpg" - - if [[ -z "$__UbuntuRepo" ]]; then - __UbuntuRepo="http://ftp.debian.org/debian/" + __CodeName=noble + if [[ -z "$__LLDB_Package" ]]; then + __LLDB_Package="liblldb-19-dev" fi ;; stretch) # Debian 9 @@ -319,7 +314,7 @@ while :; do __KeyringFile="/usr/share/keyrings/debian-archive-keyring.gpg" if [[ -z "$__UbuntuRepo" ]]; then - __UbuntuRepo="http://ftp.debian.org/debian/" + __UbuntuRepo="http://archive.debian.org/debian/" fi ;; bullseye) # Debian 11 @@ -340,10 +335,28 @@ while :; do ;; sid) # Debian sid __CodeName=sid - __KeyringFile="/usr/share/keyrings/debian-archive-keyring.gpg" + __UbuntuSuites= - if [[ -z "$__UbuntuRepo" ]]; then - __UbuntuRepo="http://ftp.debian.org/debian/" + # Debian-Ports architectures need different values + case "$__UbuntuArch" in + amd64|arm64|armel|armhf|i386|mips64el|ppc64el|riscv64|s390x) + __KeyringFile="/usr/share/keyrings/debian-archive-keyring.gpg" + + if [[ -z "$__UbuntuRepo" ]]; then + __UbuntuRepo="http://ftp.debian.org/debian/" + fi + ;; + *) + __KeyringFile="/usr/share/keyrings/debian-ports-archive-keyring.gpg" + + if [[ -z "$__UbuntuRepo" ]]; then + __UbuntuRepo="http://ftp.ports.debian.org/debian-ports/" + fi + ;; + esac + + if [[ -e "$__KeyringFile" ]]; then + __Keyring="--keyring $__KeyringFile" fi ;; tizen) @@ -370,7 +383,7 @@ while :; do ;; freebsd14) __CodeName=freebsd - __FreeBSDBase="14.0-RELEASE" + __FreeBSDBase="14.2-RELEASE" __FreeBSDABI="14" __SkipUnmount=1 ;; @@ -388,6 +401,9 @@ while :; do --skipsigcheck) __SkipSigCheck=1 ;; + --skipemulation) + __SkipEmulation=1 + ;; --rootfsdir|-rootfsdir) shift __RootfsDir="$1" @@ -420,16 +436,15 @@ case "$__AlpineVersion" in elif [[ "$__AlpineArch" == "x86" ]]; then __AlpineVersion=3.17 # minimum version that supports lldb-dev __AlpinePackages+=" llvm15-libs" - elif [[ "$__AlpineArch" == "riscv64" ]]; then + elif [[ "$__AlpineArch" == "riscv64" || "$__AlpineArch" == "loongarch64" ]]; then + __AlpineVersion=3.21 # minimum version that supports lldb-dev + __AlpinePackages+=" llvm19-libs" + elif [[ -n "$__AlpineMajorVersion" ]]; then + # use whichever alpine version is provided and select the latest toolchain libs __AlpineLlvmLibsLookup=1 - __AlpineVersion=edge # minimum version with APKINDEX.tar.gz (packages archive) else __AlpineVersion=3.13 # 3.13 to maximize compatibility __AlpinePackages+=" llvm10-libs" - - if [[ "$__AlpineArch" == "armv7" ]]; then - __AlpinePackages="${__AlpinePackages//numactl-dev/}" - fi fi esac @@ -439,15 +454,6 @@ if [[ "$__AlpineVersion" =~ 3\.1[345] ]]; then __AlpinePackages="${__AlpinePackages/compiler-rt/compiler-rt-static}" fi -if [[ "$__BuildArch" == "armel" ]]; then - __LLDB_Package="lldb-3.5-dev" -fi - -if [[ "$__CodeName" == "xenial" && "$__UbuntuArch" == "armhf" ]]; then - # libnuma-dev is not available on armhf for xenial - __UbuntuPackages="${__UbuntuPackages//libnuma-dev/}" -fi - __UbuntuPackages+=" ${__LLDB_Package:-}" if [[ -z "$__UbuntuRepo" ]]; then @@ -496,7 +502,7 @@ if [[ "$__CodeName" == "alpine" ]]; then arch="$(uname -m)" ensureDownloadTool - + if [[ "$__hasWget" == 1 ]]; then wget -P "$__ApkToolsDir" "https://gitlab.alpinelinux.org/api/v4/projects/5/packages/generic/v$__ApkToolsVersion/$arch/apk.static" else @@ -512,11 +518,6 @@ if [[ "$__CodeName" == "alpine" ]]; then echo "$__ApkToolsSHA512SUM $__ApkToolsDir/apk.static" | sha512sum -c chmod +x "$__ApkToolsDir/apk.static" - if [[ -f "/usr/bin/qemu-$__QEMUArch-static" ]]; then - mkdir -p "$__RootfsDir"/usr/bin - cp -v "/usr/bin/qemu-$__QEMUArch-static" "$__RootfsDir/usr/bin" - fi - if [[ "$__AlpineVersion" == "edge" ]]; then version=edge else @@ -536,6 +537,10 @@ if [[ "$__CodeName" == "alpine" ]]; then __ApkSignatureArg="--keys-dir $__ApkKeysDir" fi + if [[ "$__SkipEmulation" == "1" ]]; then + __NoEmulationArg="--no-scripts" + fi + # initialize DB # shellcheck disable=SC2086 "$__ApkToolsDir/apk.static" \ @@ -557,7 +562,7 @@ if [[ "$__CodeName" == "alpine" ]]; then "$__ApkToolsDir/apk.static" \ -X "http://dl-cdn.alpinelinux.org/alpine/$version/main" \ -X "http://dl-cdn.alpinelinux.org/alpine/$version/community" \ - -U $__ApkSignatureArg --root "$__RootfsDir" --arch "$__AlpineArch" \ + -U $__ApkSignatureArg --root "$__RootfsDir" --arch "$__AlpineArch" $__NoEmulationArg \ add $__AlpinePackages rm -r "$__ApkToolsDir" @@ -573,7 +578,7 @@ elif [[ "$__CodeName" == "freebsd" ]]; then curl -SL "https://download.freebsd.org/ftp/releases/${__FreeBSDArch}/${__FreeBSDMachineArch}/${__FreeBSDBase}/base.txz" | tar -C "$__RootfsDir" -Jxf - ./lib ./usr/lib ./usr/libdata ./usr/include ./usr/share/keys ./etc ./bin/freebsd-version fi echo "ABI = \"FreeBSD:${__FreeBSDABI}:${__FreeBSDMachineArch}\"; FINGERPRINTS = \"${__RootfsDir}/usr/share/keys\"; REPOS_DIR = [\"${__RootfsDir}/etc/pkg\"]; REPO_AUTOUPDATE = NO; RUN_SCRIPTS = NO;" > "${__RootfsDir}"/usr/local/etc/pkg.conf - echo "FreeBSD: { url: \"pkg+http://pkg.FreeBSD.org/\${ABI}/quarterly\", mirror_type: \"srv\", signature_type: \"fingerprints\", fingerprints: \"${__RootfsDir}/usr/share/keys/pkg\", enabled: yes }" > "${__RootfsDir}"/etc/pkg/FreeBSD.conf + echo "FreeBSD: { url: \"pkg+http://pkg.FreeBSD.org/\${ABI}/quarterly\", mirror_type: \"srv\", signature_type: \"fingerprints\", fingerprints: \"/usr/share/keys/pkg\", enabled: yes }" > "${__RootfsDir}"/etc/pkg/FreeBSD.conf mkdir -p "$__RootfsDir"/tmp # get and build package manager if [[ "$__hasWget" == 1 ]]; then @@ -681,7 +686,7 @@ elif [[ "$__CodeName" == "haiku" ]]; then ensureDownloadTool - echo "Downloading Haiku package tool" + echo "Downloading Haiku package tools" git clone https://github.com/haiku/haiku-toolchains-ubuntu --depth 1 "$__RootfsDir/tmp/script" if [[ "$__hasWget" == 1 ]]; then wget -O "$__RootfsDir/tmp/download/hosttools.zip" "$("$__RootfsDir/tmp/script/fetch.sh" --hosttools)" @@ -691,34 +696,42 @@ elif [[ "$__CodeName" == "haiku" ]]; then unzip -o "$__RootfsDir/tmp/download/hosttools.zip" -d "$__RootfsDir/tmp/bin" - DepotBaseUrl="https://depot.haiku-os.org/__api/v2/pkg/get-pkg" - HpkgBaseUrl="https://eu.hpkg.haiku-os.org/haiku/master/$__HaikuArch/current" + HaikuBaseUrl="https://eu.hpkg.haiku-os.org/haiku/master/$__HaikuArch/current" + HaikuPortsBaseUrl="https://eu.hpkg.haiku-os.org/haikuports/master/$__HaikuArch/current" + + echo "Downloading HaikuPorts package repository index..." + if [[ "$__hasWget" == 1 ]]; then + wget -P "$__RootfsDir/tmp/download" "$HaikuPortsBaseUrl/repo" + else + curl -SLO --create-dirs --output-dir "$__RootfsDir/tmp/download" "$HaikuPortsBaseUrl/repo" + fi - # Download Haiku packages echo "Downloading Haiku packages" read -ra array <<<"$__HaikuPackages" for package in "${array[@]}"; do echo "Downloading $package..." - # API documented here: https://github.com/haiku/haikudepotserver/blob/master/haikudepotserver-api2/src/main/resources/api2/pkg.yaml#L60 - # The schema here: https://github.com/haiku/haikudepotserver/blob/master/haikudepotserver-api2/src/main/resources/api2/pkg.yaml#L598 + hpkgFilename="$(LD_LIBRARY_PATH="$__RootfsDir/tmp/bin" "$__RootfsDir/tmp/bin/package_repo" list -f "$__RootfsDir/tmp/download/repo" | + grep -E "${package}-" | sort -V | tail -n 1 | xargs)" + if [ -z "$hpkgFilename" ]; then + >&2 echo "ERROR: package $package missing." + exit 1 + fi + echo "Resolved filename: $hpkgFilename..." + hpkgDownloadUrl="$HaikuPortsBaseUrl/packages/$hpkgFilename" if [[ "$__hasWget" == 1 ]]; then - hpkgDownloadUrl="$(wget -qO- --post-data '{"name":"'"$package"'","repositorySourceCode":"haikuports_'$__HaikuArch'","versionType":"LATEST","naturalLanguageCode":"en"}' \ - --header 'Content-Type:application/json' "$DepotBaseUrl" | jq -r '.result.versions[].hpkgDownloadURL')" wget -P "$__RootfsDir/tmp/download" "$hpkgDownloadUrl" else - hpkgDownloadUrl="$(curl -sSL -XPOST --data '{"name":"'"$package"'","repositorySourceCode":"haikuports_'$__HaikuArch'","versionType":"LATEST","naturalLanguageCode":"en"}' \ - --header 'Content-Type:application/json' "$DepotBaseUrl" | jq -r '.result.versions[].hpkgDownloadURL')" curl -SLO --create-dirs --output-dir "$__RootfsDir/tmp/download" "$hpkgDownloadUrl" fi done for package in haiku haiku_devel; do echo "Downloading $package..." if [[ "$__hasWget" == 1 ]]; then - hpkgVersion="$(wget -qO- "$HpkgBaseUrl" | sed -n 's/^.*version: "\([^"]*\)".*$/\1/p')" - wget -P "$__RootfsDir/tmp/download" "$HpkgBaseUrl/packages/$package-$hpkgVersion-1-$__HaikuArch.hpkg" + hpkgVersion="$(wget -qO- "$HaikuBaseUrl" | sed -n 's/^.*version: "\([^"]*\)".*$/\1/p')" + wget -P "$__RootfsDir/tmp/download" "$HaikuBaseUrl/packages/$package-$hpkgVersion-1-$__HaikuArch.hpkg" else - hpkgVersion="$(curl -sSL "$HpkgBaseUrl" | sed -n 's/^.*version: "\([^"]*\)".*$/\1/p')" - curl -SLO --create-dirs --output-dir "$__RootfsDir/tmp/download" "$HpkgBaseUrl/packages/$package-$hpkgVersion-1-$__HaikuArch.hpkg" + hpkgVersion="$(curl -sSL "$HaikuBaseUrl" | sed -n 's/^.*version: "\([^"]*\)".*$/\1/p')" + curl -SLO --create-dirs --output-dir "$__RootfsDir/tmp/download" "$HaikuBaseUrl/packages/$package-$hpkgVersion-1-$__HaikuArch.hpkg" fi done @@ -744,25 +757,67 @@ elif [[ "$__CodeName" == "haiku" ]]; then popd rm -rf "$__RootfsDir/tmp" elif [[ -n "$__CodeName" ]]; then + __Suites="$__CodeName $(for suite in $__UbuntuSuites; do echo -n "$__CodeName-$suite "; done)" + + if [[ "$__SkipEmulation" == "1" ]]; then + if [[ -z "$AR" ]]; then + if command -v ar &>/dev/null; then + AR="$(command -v ar)" + elif command -v llvm-ar &>/dev/null; then + AR="$(command -v llvm-ar)" + else + echo "Unable to find ar or llvm-ar on PATH, add them to PATH or set AR environment variable pointing to the available AR tool" + exit 1 + fi + fi + + PYTHON=${PYTHON_EXECUTABLE:-python3} + + # shellcheck disable=SC2086,SC2046 + echo running "$PYTHON" "$__CrossDir/install-debs.py" --arch "$__UbuntuArch" --mirror "$__UbuntuRepo" --rootfsdir "$__RootfsDir" --artool "$AR" \ + $(for suite in $__Suites; do echo -n "--suite $suite "; done) \ + $__UbuntuPackages + + # shellcheck disable=SC2086,SC2046 + "$PYTHON" "$__CrossDir/install-debs.py" --arch "$__UbuntuArch" --mirror "$__UbuntuRepo" --rootfsdir "$__RootfsDir" --artool "$AR" \ + $(for suite in $__Suites; do echo -n "--suite $suite "; done) \ + $__UbuntuPackages + exit 0 + fi + + __UpdateOptions= if [[ "$__SkipSigCheck" == "0" ]]; then __Keyring="$__Keyring --force-check-gpg" + else + __Keyring= + __UpdateOptions="--allow-unauthenticated --allow-insecure-repositories" fi # shellcheck disable=SC2086 echo running debootstrap "--variant=minbase" $__Keyring --arch "$__UbuntuArch" "$__CodeName" "$__RootfsDir" "$__UbuntuRepo" - debootstrap "--variant=minbase" $__Keyring --arch "$__UbuntuArch" "$__CodeName" "$__RootfsDir" "$__UbuntuRepo" + # shellcheck disable=SC2086 + if ! debootstrap "--variant=minbase" $__Keyring --arch "$__UbuntuArch" "$__CodeName" "$__RootfsDir" "$__UbuntuRepo"; then + echo "debootstrap failed! dumping debootstrap.log" + cat "$__RootfsDir/debootstrap/debootstrap.log" + exit 1 + fi + + rm -rf "$__RootfsDir"/etc/apt/*.{sources,list} "$__RootfsDir"/etc/apt/sources.list.d mkdir -p "$__RootfsDir/etc/apt/sources.list.d/" + + # shellcheck disable=SC2086 cat > "$__RootfsDir/etc/apt/sources.list.d/$__CodeName.sources" < token2) - (token1 < token2) + else: + return -1 if isinstance(token1, str) else 1 + + return len(tokens1) - len(tokens2) + +def compare_debian_versions(version1, version2): + """Compare two Debian package versions.""" + epoch1, upstream1, revision1 = parse_debian_version(version1) + epoch2, upstream2, revision2 = parse_debian_version(version2) + + if epoch1 != epoch2: + return epoch1 - epoch2 + + result = compare_upstream_version(upstream1, upstream2) + if result != 0: + return result + + return compare_upstream_version(revision1, revision2) + +def resolve_dependencies(packages, aliases, desired_packages): + """Recursively resolves dependencies for the desired packages.""" + resolved = [] + to_process = deque(desired_packages) + + while to_process: + current = to_process.popleft() + resolved_package = current if current in packages else aliases.get(current, [None])[0] + + if not resolved_package: + print(f"Error: Package '{current}' was not found in the available packages.") + sys.exit(1) + + if resolved_package not in resolved: + resolved.append(resolved_package) + + deps = packages.get(resolved_package, {}).get("Depends", "") + if deps: + deps = [dep.split(' ')[0] for dep in deps.split(', ') if dep] + for dep in deps: + if dep not in resolved and dep not in to_process and dep in packages: + to_process.append(dep) + + return resolved + +def parse_package_index(content): + """Parses the Packages.gz file and returns package information.""" + packages = {} + aliases = {} + entries = re.split(r'\n\n+', content) + + for entry in entries: + fields = dict(re.findall(r'^(\S+): (.+)$', entry, re.MULTILINE)) + if "Package" in fields: + package_name = fields["Package"] + version = fields.get("Version") + filename = fields.get("Filename") + depends = fields.get("Depends") + provides = fields.get("Provides", None) + + # Only update if package_name is not in packages or if the new version is higher + if package_name not in packages or compare_debian_versions(version, packages[package_name]["Version"]) > 0: + packages[package_name] = { + "Version": version, + "Filename": filename, + "Depends": depends + } + + # Update aliases if package provides any alternatives + if provides: + provides_list = [x.strip() for x in provides.split(",")] + for alias in provides_list: + # Strip version specifiers + alias_name = re.sub(r'\s*\(=.*\)', '', alias) + if alias_name not in aliases: + aliases[alias_name] = [] + if package_name not in aliases[alias_name]: + aliases[alias_name].append(package_name) + + return packages, aliases + +def install_packages(mirror, packages_info, aliases, tmp_dir, extract_dir, ar_tool, desired_packages): + """Downloads .deb files and extracts them.""" + resolved_packages = resolve_dependencies(packages_info, aliases, desired_packages) + print(f"Resolved packages (including dependencies): {resolved_packages}") + + packages_to_download = {} + + for pkg in resolved_packages: + if pkg in packages_info: + packages_to_download[pkg] = packages_info[pkg] + + if pkg in aliases: + for alias in aliases[pkg]: + if alias in packages_info: + packages_to_download[alias] = packages_info[alias] + + asyncio.run(download_deb_files_parallel(mirror, packages_to_download, tmp_dir)) + + package_to_deb_file_map = {} + for pkg in resolved_packages: + pkg_info = packages_info.get(pkg) + if pkg_info: + deb_filename = pkg_info.get("Filename") + if deb_filename: + deb_file_path = os.path.join(tmp_dir, os.path.basename(deb_filename)) + package_to_deb_file_map[pkg] = deb_file_path + + for pkg in reversed(resolved_packages): + deb_file = package_to_deb_file_map.get(pkg) + if deb_file and os.path.exists(deb_file): + extract_deb_file(deb_file, tmp_dir, extract_dir, ar_tool) + + print("All done!") + +def extract_deb_file(deb_file, tmp_dir, extract_dir, ar_tool): + """Extract .deb file contents""" + + os.makedirs(extract_dir, exist_ok=True) + + with tempfile.TemporaryDirectory(dir=tmp_dir) as tmp_subdir: + result = subprocess.run(f"{ar_tool} t {os.path.abspath(deb_file)}", cwd=tmp_subdir, check=True, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + + tar_filename = None + for line in result.stdout.decode().splitlines(): + if line.startswith("data.tar"): + tar_filename = line.strip() + break + + if not tar_filename: + raise FileNotFoundError(f"Could not find 'data.tar.*' in {deb_file}.") + + tar_file_path = os.path.join(tmp_subdir, tar_filename) + print(f"Extracting {tar_filename} from {deb_file}..") + + subprocess.run(f"{ar_tool} p {os.path.abspath(deb_file)} {tar_filename} > {tar_file_path}", check=True, shell=True) + + file_extension = os.path.splitext(tar_file_path)[1].lower() + + if file_extension == ".xz": + mode = "r:xz" + elif file_extension == ".gz": + mode = "r:gz" + elif file_extension == ".zst": + # zstd is not supported by standard library yet + decompressed_tar_path = tar_file_path.replace(".zst", "") + with open(tar_file_path, "rb") as zst_file, open(decompressed_tar_path, "wb") as decompressed_file: + dctx = zstandard.ZstdDecompressor() + dctx.copy_stream(zst_file, decompressed_file) + + tar_file_path = decompressed_tar_path + mode = "r" + else: + raise ValueError(f"Unsupported compression format: {file_extension}") + + with tarfile.open(tar_file_path, mode) as tar: + tar.extractall(path=extract_dir, filter='fully_trusted') + +def finalize_setup(rootfsdir): + lib_dir = os.path.join(rootfsdir, 'lib') + usr_lib_dir = os.path.join(rootfsdir, 'usr', 'lib') + + if os.path.exists(lib_dir): + if os.path.islink(lib_dir): + os.remove(lib_dir) + else: + os.makedirs(usr_lib_dir, exist_ok=True) + + for item in os.listdir(lib_dir): + src = os.path.join(lib_dir, item) + dest = os.path.join(usr_lib_dir, item) + + if os.path.isdir(src): + shutil.copytree(src, dest, dirs_exist_ok=True) + else: + shutil.copy2(src, dest) + + shutil.rmtree(lib_dir) + + os.symlink(usr_lib_dir, lib_dir) + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description="Generate rootfs for .NET runtime on Debian-like OS") + parser.add_argument("--distro", required=False, help="Distro name (e.g., debian, ubuntu, etc.)") + parser.add_argument("--arch", required=True, help="Architecture (e.g., amd64, loong64, etc.)") + parser.add_argument("--rootfsdir", required=True, help="Destination directory.") + parser.add_argument('--suite', required=True, action='append', help='Specify one or more repository suites to collect index data.') + parser.add_argument("--mirror", required=False, help="Mirror (e.g., http://ftp.debian.org/debian-ports etc.)") + parser.add_argument("--artool", required=False, default="ar", help="ar tool to extract debs (e.g., ar, llvm-ar etc.)") + parser.add_argument("packages", nargs="+", help="List of package names to be installed.") + + args = parser.parse_args() + + if args.mirror is None: + if args.distro == "ubuntu": + args.mirror = "http://archive.ubuntu.com/ubuntu" if args.arch in ["amd64", "i386"] else "http://ports.ubuntu.com/ubuntu-ports" + elif args.distro == "debian": + args.mirror = "http://ftp.debian.org/debian-ports" + else: + raise Exception("Unsupported distro") + + DESIRED_PACKAGES = args.packages + [ # base packages + "dpkg", + "busybox", + "libc-bin", + "base-files", + "base-passwd", + "debianutils" + ] + + print(f"Creating rootfs. rootfsdir: {args.rootfsdir}, distro: {args.distro}, arch: {args.arch}, suites: {args.suite}, mirror: {args.mirror}") + + package_index_content = asyncio.run(download_package_index_parallel(args.mirror, args.arch, args.suite)) + + packages_info, aliases = parse_package_index(package_index_content) + + with tempfile.TemporaryDirectory() as tmp_dir: + install_packages(args.mirror, packages_info, aliases, tmp_dir, args.rootfsdir, args.artool, DESIRED_PACKAGES) + + finalize_setup(args.rootfsdir) diff --git a/src/vstest/eng/common/cross/tizen-fetch.sh b/src/vstest/eng/common/cross/tizen-fetch.sh index 28936ceef3a..37c3a61f1de 100644 --- a/src/vstest/eng/common/cross/tizen-fetch.sh +++ b/src/vstest/eng/common/cross/tizen-fetch.sh @@ -156,13 +156,8 @@ fetch_tizen_pkgs() done } -if [ "$TIZEN_ARCH" == "riscv64" ]; then - BASE="Tizen-Base-RISCV" - UNIFIED="Tizen-Unified-RISCV" -else - BASE="Tizen-Base" - UNIFIED="Tizen-Unified" -fi +BASE="Tizen-Base" +UNIFIED="Tizen-Unified" Inform "Initialize ${TIZEN_ARCH} base" fetch_tizen_pkgs_init standard $BASE diff --git a/src/vstest/eng/common/cross/toolchain.cmake b/src/vstest/eng/common/cross/toolchain.cmake index 9a7ecfbd42c..0ff85cf0367 100644 --- a/src/vstest/eng/common/cross/toolchain.cmake +++ b/src/vstest/eng/common/cross/toolchain.cmake @@ -67,6 +67,13 @@ elseif(TARGET_ARCH_NAME STREQUAL "armv6") else() set(TOOLCHAIN "arm-linux-gnueabihf") endif() +elseif(TARGET_ARCH_NAME STREQUAL "loongarch64") + set(CMAKE_SYSTEM_PROCESSOR "loongarch64") + if(EXISTS ${CROSS_ROOTFS}/usr/lib/gcc/loongarch64-alpine-linux-musl) + set(TOOLCHAIN "loongarch64-alpine-linux-musl") + else() + set(TOOLCHAIN "loongarch64-linux-gnu") + endif() elseif(TARGET_ARCH_NAME STREQUAL "ppc64le") set(CMAKE_SYSTEM_PROCESSOR ppc64le) if(EXISTS ${CROSS_ROOTFS}/usr/lib/gcc/powerpc64le-alpine-linux-musl) @@ -118,7 +125,7 @@ elseif(TARGET_ARCH_NAME STREQUAL "x86") set(TIZEN_TOOLCHAIN "i586-tizen-linux-gnu") endif() else() - message(FATAL_ERROR "Arch is ${TARGET_ARCH_NAME}. Only arm, arm64, armel, armv6, ppc64le, riscv64, s390x, x64 and x86 are supported!") + message(FATAL_ERROR "Arch is ${TARGET_ARCH_NAME}. Only arm, arm64, armel, armv6, loongarch64, ppc64le, riscv64, s390x, x64 and x86 are supported!") endif() if(DEFINED ENV{TOOLCHAIN}) @@ -148,6 +155,25 @@ if(TIZEN) include_directories(SYSTEM ${TIZEN_TOOLCHAIN_PATH}/include/c++/${TIZEN_TOOLCHAIN}) endif() +function(locate_toolchain_exec exec var) + set(TOOLSET_PREFIX ${TOOLCHAIN}-) + string(TOUPPER ${exec} EXEC_UPPERCASE) + if(NOT "$ENV{CLR_${EXEC_UPPERCASE}}" STREQUAL "") + set(${var} "$ENV{CLR_${EXEC_UPPERCASE}}" PARENT_SCOPE) + return() + endif() + + find_program(EXEC_LOCATION_${exec} + NAMES + "${TOOLSET_PREFIX}${exec}${CLR_CMAKE_COMPILER_FILE_NAME_VERSION}" + "${TOOLSET_PREFIX}${exec}") + + if (EXEC_LOCATION_${exec} STREQUAL "EXEC_LOCATION_${exec}-NOTFOUND") + message(FATAL_ERROR "Unable to find toolchain executable. Name: ${exec}, Prefix: ${TOOLSET_PREFIX}.") + endif() + set(${var} ${EXEC_LOCATION_${exec}} PARENT_SCOPE) +endfunction() + if(ANDROID) if(TARGET_ARCH_NAME STREQUAL "arm") set(ANDROID_ABI armeabi-v7a) @@ -178,66 +204,24 @@ elseif(FREEBSD) set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -fuse-ld=lld") elseif(ILLUMOS) set(CMAKE_SYSROOT "${CROSS_ROOTFS}") + set(CMAKE_SYSTEM_PREFIX_PATH "${CROSS_ROOTFS}") + set(CMAKE_C_STANDARD_LIBRARIES "${CMAKE_C_STANDARD_LIBRARIES} -lssp") + set(CMAKE_CXX_STANDARD_LIBRARIES "${CMAKE_CXX_STANDARD_LIBRARIES} -lssp") include_directories(SYSTEM ${CROSS_ROOTFS}/include) - set(TOOLSET_PREFIX ${TOOLCHAIN}-) - function(locate_toolchain_exec exec var) - string(TOUPPER ${exec} EXEC_UPPERCASE) - if(NOT "$ENV{CLR_${EXEC_UPPERCASE}}" STREQUAL "") - set(${var} "$ENV{CLR_${EXEC_UPPERCASE}}" PARENT_SCOPE) - return() - endif() - - find_program(EXEC_LOCATION_${exec} - NAMES - "${TOOLSET_PREFIX}${exec}${CLR_CMAKE_COMPILER_FILE_NAME_VERSION}" - "${TOOLSET_PREFIX}${exec}") - - if (EXEC_LOCATION_${exec} STREQUAL "EXEC_LOCATION_${exec}-NOTFOUND") - message(FATAL_ERROR "Unable to find toolchain executable. Name: ${exec}, Prefix: ${TOOLSET_PREFIX}.") - endif() - set(${var} ${EXEC_LOCATION_${exec}} PARENT_SCOPE) - endfunction() - - set(CMAKE_SYSTEM_PREFIX_PATH "${CROSS_ROOTFS}") - locate_toolchain_exec(gcc CMAKE_C_COMPILER) locate_toolchain_exec(g++ CMAKE_CXX_COMPILER) - - set(CMAKE_C_STANDARD_LIBRARIES "${CMAKE_C_STANDARD_LIBRARIES} -lssp") - set(CMAKE_CXX_STANDARD_LIBRARIES "${CMAKE_CXX_STANDARD_LIBRARIES} -lssp") elseif(HAIKU) set(CMAKE_SYSROOT "${CROSS_ROOTFS}") set(CMAKE_PROGRAM_PATH "${CMAKE_PROGRAM_PATH};${CROSS_ROOTFS}/cross-tools-x86_64/bin") - - set(TOOLSET_PREFIX ${TOOLCHAIN}-) - function(locate_toolchain_exec exec var) - string(TOUPPER ${exec} EXEC_UPPERCASE) - if(NOT "$ENV{CLR_${EXEC_UPPERCASE}}" STREQUAL "") - set(${var} "$ENV{CLR_${EXEC_UPPERCASE}}" PARENT_SCOPE) - return() - endif() - - find_program(EXEC_LOCATION_${exec} - NAMES - "${TOOLSET_PREFIX}${exec}${CLR_CMAKE_COMPILER_FILE_NAME_VERSION}" - "${TOOLSET_PREFIX}${exec}") - - if (EXEC_LOCATION_${exec} STREQUAL "EXEC_LOCATION_${exec}-NOTFOUND") - message(FATAL_ERROR "Unable to find toolchain executable. Name: ${exec}, Prefix: ${TOOLSET_PREFIX}.") - endif() - set(${var} ${EXEC_LOCATION_${exec}} PARENT_SCOPE) - endfunction() - set(CMAKE_SYSTEM_PREFIX_PATH "${CROSS_ROOTFS}") + set(CMAKE_C_STANDARD_LIBRARIES "${CMAKE_C_STANDARD_LIBRARIES} -lssp") + set(CMAKE_CXX_STANDARD_LIBRARIES "${CMAKE_CXX_STANDARD_LIBRARIES} -lssp") locate_toolchain_exec(gcc CMAKE_C_COMPILER) locate_toolchain_exec(g++ CMAKE_CXX_COMPILER) - set(CMAKE_C_STANDARD_LIBRARIES "${CMAKE_C_STANDARD_LIBRARIES} -lssp") - set(CMAKE_CXX_STANDARD_LIBRARIES "${CMAKE_CXX_STANDARD_LIBRARIES} -lssp") - # let CMake set up the correct search paths include(Platform/Haiku) else() @@ -307,7 +291,7 @@ endif() # Specify compile options -if((TARGET_ARCH_NAME MATCHES "^(arm|arm64|armel|armv6|ppc64le|riscv64|s390x|x64|x86)$" AND NOT ANDROID AND NOT FREEBSD) OR ILLUMOS OR HAIKU) +if((TARGET_ARCH_NAME MATCHES "^(arm|arm64|armel|armv6|loongarch64|ppc64le|riscv64|s390x|x64|x86)$" AND NOT ANDROID AND NOT FREEBSD) OR ILLUMOS OR HAIKU) set(CMAKE_C_COMPILER_TARGET ${TOOLCHAIN}) set(CMAKE_CXX_COMPILER_TARGET ${TOOLCHAIN}) set(CMAKE_ASM_COMPILER_TARGET ${TOOLCHAIN}) diff --git a/src/vstest/eng/common/darc-init.sh b/src/vstest/eng/common/darc-init.sh index 36dbd45e1ce..e889f439b8d 100644 --- a/src/vstest/eng/common/darc-init.sh +++ b/src/vstest/eng/common/darc-init.sh @@ -68,7 +68,7 @@ function InstallDarcCli { fi fi - local arcadeServicesSource="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json" + local arcadeServicesSource="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng/nuget/v3/index.json" echo "Installing Darc CLI version $darcVersion..." echo "You may need to restart your command shell if this is the first dotnet tool you have installed." diff --git a/src/vstest/eng/common/dotnet.cmd b/src/vstest/eng/common/dotnet.cmd new file mode 100644 index 00000000000..527fa4bb38f --- /dev/null +++ b/src/vstest/eng/common/dotnet.cmd @@ -0,0 +1,7 @@ +@echo off + +:: This script is used to install the .NET SDK. +:: It will also invoke the SDK with any provided arguments. + +powershell -ExecutionPolicy ByPass -NoProfile -command "& """%~dp0dotnet.ps1""" %*" +exit /b %ErrorLevel% diff --git a/src/vstest/eng/common/dotnet.ps1 b/src/vstest/eng/common/dotnet.ps1 new file mode 100644 index 00000000000..45e5676c9eb --- /dev/null +++ b/src/vstest/eng/common/dotnet.ps1 @@ -0,0 +1,11 @@ +# This script is used to install the .NET SDK. +# It will also invoke the SDK with any provided arguments. + +. $PSScriptRoot\tools.ps1 +$dotnetRoot = InitializeDotNetCli -install:$true + +# Invoke acquired SDK with args if they are provided +if ($args.count -gt 0) { + $env:DOTNET_NOLOGO=1 + & "$dotnetRoot\dotnet.exe" $args +} diff --git a/src/vstest/eng/common/dotnet.sh b/src/vstest/eng/common/dotnet.sh new file mode 100644 index 00000000000..2ef68235675 --- /dev/null +++ b/src/vstest/eng/common/dotnet.sh @@ -0,0 +1,26 @@ +#!/usr/bin/env bash + +# This script is used to install the .NET SDK. +# It will also invoke the SDK with any provided arguments. + +source="${BASH_SOURCE[0]}" +# resolve $SOURCE until the file is no longer a symlink +while [[ -h $source ]]; do + scriptroot="$( cd -P "$( dirname "$source" )" && pwd )" + source="$(readlink "$source")" + + # if $source was a relative symlink, we need to resolve it relative to the path where the + # symlink file was located + [[ $source != /* ]] && source="$scriptroot/$source" +done +scriptroot="$( cd -P "$( dirname "$source" )" && pwd )" + +source $scriptroot/tools.sh +InitializeDotNetCli true # install + +# Invoke acquired SDK with args if they are provided +if [[ $# > 0 ]]; then + __dotnetDir=${_InitializeDotNetCli} + dotnetPath=${__dotnetDir}/dotnet + ${dotnetPath} "$@" +fi diff --git a/src/vstest/eng/common/internal/NuGet.config b/src/vstest/eng/common/internal/NuGet.config index 19d3d311b16..f70261ed689 100644 --- a/src/vstest/eng/common/internal/NuGet.config +++ b/src/vstest/eng/common/internal/NuGet.config @@ -4,4 +4,7 @@ + + + diff --git a/src/vstest/eng/common/native/install-dependencies.sh b/src/vstest/eng/common/native/install-dependencies.sh new file mode 100644 index 00000000000..477a44f335b --- /dev/null +++ b/src/vstest/eng/common/native/install-dependencies.sh @@ -0,0 +1,62 @@ +#!/bin/sh + +set -e + +# This is a simple script primarily used for CI to install necessary dependencies +# +# Usage: +# +# ./install-dependencies.sh + +os="$(echo "$1" | tr "[:upper:]" "[:lower:]")" + +if [ -z "$os" ]; then + . "$(dirname "$0")"/init-os-and-arch.sh +fi + +case "$os" in + linux) + if [ -e /etc/os-release ]; then + . /etc/os-release + fi + + if [ "$ID" = "debian" ] || [ "$ID_LIKE" = "debian" ]; then + apt update + + apt install -y build-essential gettext locales cmake llvm clang lld lldb liblldb-dev libunwind8-dev libicu-dev liblttng-ust-dev \ + libssl-dev libkrb5-dev pigz cpio + + localedef -i en_US -c -f UTF-8 -A /usr/share/locale/locale.alias en_US.UTF-8 + elif [ "$ID" = "fedora" ] || [ "$ID" = "rhel" ] || [ "$ID" = "azurelinux" ]; then + pkg_mgr="$(command -v tdnf 2>/dev/null || command -v dnf)" + $pkg_mgr install -y cmake llvm lld lldb clang python curl libicu-devel openssl-devel krb5-devel lttng-ust-devel pigz cpio + elif [ "$ID" = "alpine" ]; then + apk add build-base cmake bash curl clang llvm-dev lld lldb krb5-dev lttng-ust-dev icu-dev openssl-dev pigz cpio + else + echo "Unsupported distro. distro: $ID" + exit 1 + fi + ;; + + osx|maccatalyst|ios|iossimulator|tvos|tvossimulator) + echo "Installed xcode version: $(xcode-select -p)" + + export HOMEBREW_NO_INSTALL_CLEANUP=1 + export HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1 + # Skip brew update for now, see https://github.com/actions/setup-python/issues/577 + # brew update --preinstall + brew bundle --no-upgrade --file=- < Msbuild engine to use to run build ('dotnet', 'vs', or unspecified)." + Write-Host " -excludeCIBinaryLog When running on CI, allow no binary log (short: -nobl)" Write-Host "" Write-Host "Command line arguments not listed above are passed thru to msbuild." } @@ -34,10 +36,11 @@ function Print-Usage() { function Build([string]$target) { $logSuffix = if ($target -eq 'Execute') { '' } else { ".$target" } $log = Join-Path $LogDir "$task$logSuffix.binlog" + $binaryLogArg = if ($binaryLog) { "/bl:$log" } else { "" } $outputPath = Join-Path $ToolsetDir "$task\" MSBuild $taskProject ` - /bl:$log ` + $binaryLogArg ` /t:$target ` /p:Configuration=$configuration ` /p:RepoRoot=$RepoRoot ` @@ -64,7 +67,7 @@ try { $GlobalJson.tools | Add-Member -Name "vs" -Value (ConvertFrom-Json "{ `"version`": `"16.5`" }") -MemberType NoteProperty } if( -not ($GlobalJson.tools.PSObject.Properties.Name -match "xcopy-msbuild" )) { - $GlobalJson.tools | Add-Member -Name "xcopy-msbuild" -Value "17.12.0" -MemberType NoteProperty + $GlobalJson.tools | Add-Member -Name "xcopy-msbuild" -Value "17.13.0" -MemberType NoteProperty } if ($GlobalJson.tools."xcopy-msbuild".Trim() -ine "none") { $xcopyMSBuildToolsFolder = InitializeXCopyMSBuild $GlobalJson.tools."xcopy-msbuild" -install $true diff --git a/src/vstest/eng/common/sdk-task.sh b/src/vstest/eng/common/sdk-task.sh new file mode 100644 index 00000000000..2f83adc0269 --- /dev/null +++ b/src/vstest/eng/common/sdk-task.sh @@ -0,0 +1,116 @@ +#!/usr/bin/env bash + +show_usage() { + echo "Common settings:" + echo " --task Name of Arcade task (name of a project in SdkTasks directory of the Arcade SDK package)" + echo " --restore Restore dependencies" + echo " --verbosity Msbuild verbosity: q[uiet], m[inimal], n[ormal], d[etailed], and diag[nostic]" + echo " --help Print help and exit" + echo "" + + echo "Advanced settings:" + echo " --excludeCIBinarylog Don't output binary log (short: -nobl)" + echo "" + echo "Command line arguments not listed above are passed thru to msbuild." +} + +source="${BASH_SOURCE[0]}" + +# resolve $source until the file is no longer a symlink +while [[ -h "$source" ]]; do + scriptroot="$( cd -P "$( dirname "$source" )" && pwd )" + source="$(readlink "$source")" + # if $source was a relative symlink, we need to resolve it relative to the path where the + # symlink file was located + [[ $source != /* ]] && source="$scriptroot/$source" +done +scriptroot="$( cd -P "$( dirname "$source" )" && pwd )" + +Build() { + local target=$1 + local log_suffix="" + [[ "$target" != "Execute" ]] && log_suffix=".$target" + local log="$log_dir/$task$log_suffix.binlog" + local binaryLogArg="" + [[ $binary_log == true ]] && binaryLogArg="/bl:$log" + local output_path="$toolset_dir/$task/" + + MSBuild "$taskProject" \ + $binaryLogArg \ + /t:"$target" \ + /p:Configuration="$configuration" \ + /p:RepoRoot="$repo_root" \ + /p:BaseIntermediateOutputPath="$output_path" \ + /v:"$verbosity" \ + $properties +} + +binary_log=true +configuration="Debug" +verbosity="minimal" +exclude_ci_binary_log=false +restore=false +help=false +properties='' + +while (($# > 0)); do + lowerI="$(echo $1 | tr "[:upper:]" "[:lower:]")" + case $lowerI in + --task) + task=$2 + shift 2 + ;; + --restore) + restore=true + shift 1 + ;; + --verbosity) + verbosity=$2 + shift 2 + ;; + --excludecibinarylog|--nobl) + binary_log=false + exclude_ci_binary_log=true + shift 1 + ;; + --help) + help=true + shift 1 + ;; + *) + properties="$properties $1" + shift 1 + ;; + esac +done + +ci=true +warnAsError=true + +if $help; then + show_usage + exit 0 +fi + +. "$scriptroot/tools.sh" +InitializeToolset + +if [[ -z "$task" ]]; then + Write-PipelineTelemetryError -Category 'Task' -Name 'MissingTask' -Message "Missing required parameter '-task '" + ExitWithExitCode 1 +fi + +taskProject=$(GetSdkTaskProject "$task") +if [[ ! -e "$taskProject" ]]; then + Write-PipelineTelemetryError -Category 'Task' -Name 'UnknownTask' -Message "Unknown task: $task" + ExitWithExitCode 1 +fi + +if $restore; then + Build "Restore" +fi + +Build "Execute" + + +ExitWithExitCode 0 diff --git a/src/vstest/eng/common/sdl/packages.config b/src/vstest/eng/common/sdl/packages.config index 4585cfd6bba..e5f543ea68c 100644 --- a/src/vstest/eng/common/sdl/packages.config +++ b/src/vstest/eng/common/sdl/packages.config @@ -1,4 +1,4 @@ - + diff --git a/src/vstest/eng/common/templates-official/job/job.yml b/src/vstest/eng/common/templates-official/job/job.yml index 817555505aa..a8a94328745 100644 --- a/src/vstest/eng/common/templates-official/job/job.yml +++ b/src/vstest/eng/common/templates-official/job/job.yml @@ -31,6 +31,7 @@ jobs: PathtoPublish: '$(Build.ArtifactStagingDirectory)/artifacts' ArtifactName: ${{ coalesce(parameters.artifacts.publish.artifacts.name , 'Artifacts_$(Agent.Os)_$(_BuildConfig)') }} condition: always() + retryCountOnTaskFailure: 10 # for any logs being locked continueOnError: true - ${{ if and(ne(parameters.artifacts.publish.logs, 'false'), ne(parameters.artifacts.publish.logs, '')) }}: - output: pipelineArtifact @@ -39,6 +40,7 @@ jobs: displayName: 'Publish logs' continueOnError: true condition: always() + retryCountOnTaskFailure: 10 # for any logs being locked sbomEnabled: false # we don't need SBOM for logs - ${{ if eq(parameters.enablePublishBuildArtifacts, true) }}: @@ -46,7 +48,7 @@ jobs: displayName: Publish Logs PathtoPublish: '$(Build.ArtifactStagingDirectory)/artifacts/log/$(_BuildConfig)' publishLocation: Container - ArtifactName: ${{ coalesce(parameters.enablePublishBuildArtifacts.artifactName, '$(Agent.Os)_$(Agent.JobName)' ) }} + ArtifactName: ${{ coalesce(parameters.enablePublishBuildArtifacts.artifactName, '$(Agent.Os)_$(Agent.JobName)_Attempt$(System.JobAttempt)' ) }} continueOnError: true condition: always() sbomEnabled: false # we don't need SBOM for logs diff --git a/src/vstest/eng/common/templates-official/steps/publish-build-artifacts.yml b/src/vstest/eng/common/templates-official/steps/publish-build-artifacts.yml index 100a3fc9849..fcf6637b2eb 100644 --- a/src/vstest/eng/common/templates-official/steps/publish-build-artifacts.yml +++ b/src/vstest/eng/common/templates-official/steps/publish-build-artifacts.yml @@ -24,6 +24,10 @@ parameters: - name: is1ESPipeline type: boolean default: true + +- name: retryCountOnTaskFailure + type: string + default: 10 steps: - ${{ if ne(parameters.is1ESPipeline, true) }}: @@ -38,4 +42,5 @@ steps: PathtoPublish: ${{ parameters.pathToPublish }} ${{ if parameters.artifactName }}: ArtifactName: ${{ parameters.artifactName }} - + ${{ if parameters.retryCountOnTaskFailure }}: + retryCountOnTaskFailure: ${{ parameters.retryCountOnTaskFailure }} diff --git a/src/vstest/eng/common/templates-official/steps/source-index-stage1-publish.yml b/src/vstest/eng/common/templates-official/steps/source-index-stage1-publish.yml new file mode 100644 index 00000000000..9b8b80942b5 --- /dev/null +++ b/src/vstest/eng/common/templates-official/steps/source-index-stage1-publish.yml @@ -0,0 +1,7 @@ +steps: +- template: /eng/common/core-templates/steps/source-index-stage1-publish.yml + parameters: + is1ESPipeline: true + + ${{ each parameter in parameters }}: + ${{ parameter.key }}: ${{ parameter.value }} diff --git a/src/vstest/eng/common/templates/job/job.yml b/src/vstest/eng/common/templates/job/job.yml index d1aeb92fcea..7cbf668c22b 100644 --- a/src/vstest/eng/common/templates/job/job.yml +++ b/src/vstest/eng/common/templates/job/job.yml @@ -46,6 +46,7 @@ jobs: artifactName: ${{ coalesce(parameters.artifacts.publish.artifacts.name , 'Artifacts_$(Agent.Os)_$(_BuildConfig)') }} continueOnError: true condition: always() + retryCountOnTaskFailure: 10 # for any logs being locked - ${{ if and(ne(parameters.artifacts.publish.logs, 'false'), ne(parameters.artifacts.publish.logs, '')) }}: - template: /eng/common/core-templates/steps/publish-pipeline-artifacts.yml parameters: @@ -56,6 +57,7 @@ jobs: displayName: 'Publish logs' continueOnError: true condition: always() + retryCountOnTaskFailure: 10 # for any logs being locked sbomEnabled: false # we don't need SBOM for logs - ${{ if ne(parameters.enablePublishBuildArtifacts, 'false') }}: @@ -66,7 +68,7 @@ jobs: displayName: Publish Logs pathToPublish: '$(Build.ArtifactStagingDirectory)/artifacts/log/$(_BuildConfig)' publishLocation: Container - artifactName: ${{ coalesce(parameters.enablePublishBuildArtifacts.artifactName, '$(Agent.Os)_$(Agent.JobName)' ) }} + artifactName: ${{ coalesce(parameters.enablePublishBuildArtifacts.artifactName, '$(Agent.Os)_$(Agent.JobName)_Attempt$(System.JobAttempt)' ) }} continueOnError: true condition: always() diff --git a/src/vstest/eng/common/templates/steps/publish-build-artifacts.yml b/src/vstest/eng/common/templates/steps/publish-build-artifacts.yml index 6428a98dfef..605e602e94d 100644 --- a/src/vstest/eng/common/templates/steps/publish-build-artifacts.yml +++ b/src/vstest/eng/common/templates/steps/publish-build-artifacts.yml @@ -25,6 +25,10 @@ parameters: type: string default: 'Container' +- name: retryCountOnTaskFailure + type: string + default: 10 + steps: - ${{ if eq(parameters.is1ESPipeline, true) }}: - 'eng/common/templates cannot be referenced from a 1ES managed template': error @@ -37,4 +41,6 @@ steps: PublishLocation: ${{ parameters.publishLocation }} PathtoPublish: ${{ parameters.pathToPublish }} ${{ if parameters.artifactName }}: - ArtifactName: ${{ parameters.artifactName }} \ No newline at end of file + ArtifactName: ${{ parameters.artifactName }} + ${{ if parameters.retryCountOnTaskFailure }}: + retryCountOnTaskFailure: ${{ parameters.retryCountOnTaskFailure }} diff --git a/src/vstest/eng/common/templates/steps/source-index-stage1-publish.yml b/src/vstest/eng/common/templates/steps/source-index-stage1-publish.yml new file mode 100644 index 00000000000..182cec33a7b --- /dev/null +++ b/src/vstest/eng/common/templates/steps/source-index-stage1-publish.yml @@ -0,0 +1,7 @@ +steps: +- template: /eng/common/core-templates/steps/source-index-stage1-publish.yml + parameters: + is1ESPipeline: false + + ${{ each parameter in parameters }}: + ${{ parameter.key }}: ${{ parameter.value }} diff --git a/src/vstest/eng/common/templates/steps/vmr-sync.yml b/src/vstest/eng/common/templates/steps/vmr-sync.yml new file mode 100644 index 00000000000..599afb6186b --- /dev/null +++ b/src/vstest/eng/common/templates/steps/vmr-sync.yml @@ -0,0 +1,207 @@ +### These steps synchronize new code from product repositories into the VMR (https://github.com/dotnet/dotnet). +### They initialize the darc CLI and pull the new updates. +### Changes are applied locally onto the already cloned VMR (located in $vmrPath). + +parameters: +- name: targetRef + displayName: Target revision in dotnet/ to synchronize + type: string + default: $(Build.SourceVersion) + +- name: vmrPath + displayName: Path where the dotnet/dotnet is checked out to + type: string + default: $(Agent.BuildDirectory)/vmr + +- name: additionalSyncs + displayName: Optional list of package names whose repo's source will also be synchronized in the local VMR, e.g. NuGet.Protocol + type: object + default: [] + +steps: +- checkout: vmr + displayName: Clone dotnet/dotnet + path: vmr + clean: true + +- checkout: self + displayName: Clone $(Build.Repository.Name) + path: repo + fetchDepth: 0 + +# This step is needed so that when we get a detached HEAD / shallow clone, +# we still pull the commit into the temporary repo clone to use it during the sync. +# Also unshallow the clone so that forwardflow command would work. +- script: | + git branch repo-head + git rev-parse HEAD + displayName: Label PR commit + workingDirectory: $(Agent.BuildDirectory)/repo + +- script: | + vmr_sha=$(grep -oP '(?<=Sha=")[^"]*' $(Agent.BuildDirectory)/repo/eng/Version.Details.xml) + echo "##vso[task.setvariable variable=vmr_sha]$vmr_sha" + displayName: Obtain the vmr sha from Version.Details.xml (Unix) + condition: ne(variables['Agent.OS'], 'Windows_NT') + workingDirectory: $(Agent.BuildDirectory)/repo + +- powershell: | + [xml]$xml = Get-Content -Path $(Agent.BuildDirectory)/repo/eng/Version.Details.xml + $vmr_sha = $xml.SelectSingleNode("//Source").Sha + Write-Output "##vso[task.setvariable variable=vmr_sha]$vmr_sha" + displayName: Obtain the vmr sha from Version.Details.xml (Windows) + condition: eq(variables['Agent.OS'], 'Windows_NT') + workingDirectory: $(Agent.BuildDirectory)/repo + +- script: | + git fetch --all + git checkout $(vmr_sha) + displayName: Checkout VMR at correct sha for repo flow + workingDirectory: ${{ parameters.vmrPath }} + +- script: | + git config --global user.name "dotnet-maestro[bot]" + git config --global user.email "dotnet-maestro[bot]@users.noreply.github.com" + displayName: Set git author to dotnet-maestro[bot] + workingDirectory: ${{ parameters.vmrPath }} + +- script: | + ./eng/common/vmr-sync.sh \ + --vmr ${{ parameters.vmrPath }} \ + --tmp $(Agent.TempDirectory) \ + --azdev-pat '$(dn-bot-all-orgs-code-r)' \ + --ci \ + --debug + + if [ "$?" -ne 0 ]; then + echo "##vso[task.logissue type=error]Failed to synchronize the VMR" + exit 1 + fi + displayName: Sync repo into VMR (Unix) + condition: ne(variables['Agent.OS'], 'Windows_NT') + workingDirectory: $(Agent.BuildDirectory)/repo + +- script: | + git config --global diff.astextplain.textconv echo + git config --system core.longpaths true + displayName: Configure Windows git (longpaths, astextplain) + condition: eq(variables['Agent.OS'], 'Windows_NT') + +- powershell: | + ./eng/common/vmr-sync.ps1 ` + -vmr ${{ parameters.vmrPath }} ` + -tmp $(Agent.TempDirectory) ` + -azdevPat '$(dn-bot-all-orgs-code-r)' ` + -ci ` + -debugOutput + + if ($LASTEXITCODE -ne 0) { + echo "##vso[task.logissue type=error]Failed to synchronize the VMR" + exit 1 + } + displayName: Sync repo into VMR (Windows) + condition: eq(variables['Agent.OS'], 'Windows_NT') + workingDirectory: $(Agent.BuildDirectory)/repo + +- ${{ if eq(variables['Build.Reason'], 'PullRequest') }}: + - task: CopyFiles@2 + displayName: Collect failed patches + condition: failed() + inputs: + SourceFolder: '$(Agent.TempDirectory)' + Contents: '*.patch' + TargetFolder: '$(Build.ArtifactStagingDirectory)/FailedPatches' + + - publish: '$(Build.ArtifactStagingDirectory)/FailedPatches' + artifact: $(System.JobDisplayName)_FailedPatches + displayName: Upload failed patches + condition: failed() + +- ${{ each assetName in parameters.additionalSyncs }}: + # The vmr-sync script ends up staging files in the local VMR so we have to commit those + - script: + git commit --allow-empty -am "Forward-flow $(Build.Repository.Name)" + displayName: Commit local VMR changes + workingDirectory: ${{ parameters.vmrPath }} + + - script: | + set -ex + + echo "Searching for details of asset ${{ assetName }}..." + + # Use darc to get dependencies information + dependencies=$(./.dotnet/dotnet darc get-dependencies --name '${{ assetName }}' --ci) + + # Extract repository URL and commit hash + repository=$(echo "$dependencies" | grep 'Repo:' | sed 's/Repo:[[:space:]]*//' | head -1) + + if [ -z "$repository" ]; then + echo "##vso[task.logissue type=error]Asset ${{ assetName }} not found in the dependency list" + exit 1 + fi + + commit=$(echo "$dependencies" | grep 'Commit:' | sed 's/Commit:[[:space:]]*//' | head -1) + + echo "Updating the VMR from $repository / $commit..." + cd .. + git clone $repository ${{ assetName }} + cd ${{ assetName }} + git checkout $commit + git branch "sync/$commit" + + ./eng/common/vmr-sync.sh \ + --vmr ${{ parameters.vmrPath }} \ + --tmp $(Agent.TempDirectory) \ + --azdev-pat '$(dn-bot-all-orgs-code-r)' \ + --ci \ + --debug + + if [ "$?" -ne 0 ]; then + echo "##vso[task.logissue type=error]Failed to synchronize the VMR" + exit 1 + fi + displayName: Sync ${{ assetName }} into (Unix) + condition: ne(variables['Agent.OS'], 'Windows_NT') + workingDirectory: $(Agent.BuildDirectory)/repo + + - powershell: | + $ErrorActionPreference = 'Stop' + + Write-Host "Searching for details of asset ${{ assetName }}..." + + $dependencies = .\.dotnet\dotnet darc get-dependencies --name '${{ assetName }}' --ci + + $repository = $dependencies | Select-String -Pattern 'Repo:\s+([^\s]+)' | Select-Object -First 1 + $repository -match 'Repo:\s+([^\s]+)' | Out-Null + $repository = $matches[1] + + if ($repository -eq $null) { + Write-Error "Asset ${{ assetName }} not found in the dependency list" + exit 1 + } + + $commit = $dependencies | Select-String -Pattern 'Commit:\s+([^\s]+)' | Select-Object -First 1 + $commit -match 'Commit:\s+([^\s]+)' | Out-Null + $commit = $matches[1] + + Write-Host "Updating the VMR from $repository / $commit..." + cd .. + git clone $repository ${{ assetName }} + cd ${{ assetName }} + git checkout $commit + git branch "sync/$commit" + + .\eng\common\vmr-sync.ps1 ` + -vmr ${{ parameters.vmrPath }} ` + -tmp $(Agent.TempDirectory) ` + -azdevPat '$(dn-bot-all-orgs-code-r)' ` + -ci ` + -debugOutput + + if ($LASTEXITCODE -ne 0) { + echo "##vso[task.logissue type=error]Failed to synchronize the VMR" + exit 1 + } + displayName: Sync ${{ assetName }} into (Windows) + condition: ne(variables['Agent.OS'], 'Windows_NT') + workingDirectory: $(Agent.BuildDirectory)/repo diff --git a/src/vstest/eng/common/templates/vmr-build-pr.yml b/src/vstest/eng/common/templates/vmr-build-pr.yml new file mode 100644 index 00000000000..ce3c29a62fa --- /dev/null +++ b/src/vstest/eng/common/templates/vmr-build-pr.yml @@ -0,0 +1,42 @@ +# This pipeline is used for running the VMR verification of the PR changes in repo-level PRs. +# +# It will run a full set of verification jobs defined in: +# https://github.com/dotnet/dotnet/blob/10060d128e3f470e77265f8490f5e4f72dae738e/eng/pipelines/templates/stages/vmr-build.yml#L27-L38 +# +# For repos that do not need to run the full set, you would do the following: +# +# 1. Copy this YML file to a repo-specific location, i.e. outside of eng/common. +# +# 2. Add `verifications` parameter to VMR template reference +# +# Examples: +# - For source-build stage 1 verification, add the following: +# verifications: [ "source-build-stage1" ] +# +# - For Windows only verifications, add the following: +# verifications: [ "unified-build-windows-x64", "unified-build-windows-x86" ] + +trigger: none +pr: none + +variables: +- template: /eng/common/templates/variables/pool-providers.yml@self + +- name: skipComponentGovernanceDetection # we run CG on internal builds only + value: true + +- name: Codeql.Enabled # we run CodeQL on internal builds only + value: false + +resources: + repositories: + - repository: vmr + type: github + name: dotnet/dotnet + endpoint: dotnet + +stages: +- template: /eng/pipelines/templates/stages/vmr-build.yml@vmr + parameters: + isBuiltFromVmr: false + scope: lite diff --git a/src/vstest/eng/common/tools.ps1 b/src/vstest/eng/common/tools.ps1 index 22b49e09d09..40f0aa86128 100644 --- a/src/vstest/eng/common/tools.ps1 +++ b/src/vstest/eng/common/tools.ps1 @@ -65,10 +65,8 @@ $ErrorActionPreference = 'Stop' # Base-64 encoded SAS token that has permission to storage container described by $runtimeSourceFeed [string]$runtimeSourceFeedKey = if (Test-Path variable:runtimeSourceFeedKey) { $runtimeSourceFeedKey } else { $null } -# True if the build is a product build -[bool]$productBuild = if (Test-Path variable:productBuild) { $productBuild } else { $false } - -[String[]]$properties = if (Test-Path variable:properties) { $properties } else { @() } +# True when the build is running within the VMR. +[bool]$fromVMR = if (Test-Path variable:fromVMR) { $fromVMR } else { $false } function Create-Directory ([string[]] $path) { New-Item -Path $path -Force -ItemType 'Directory' | Out-Null @@ -383,8 +381,8 @@ function InitializeVisualStudioMSBuild([bool]$install, [object]$vsRequirements = # If the version of msbuild is going to be xcopied, # use this version. Version matches a package here: - # https://dev.azure.com/dnceng/public/_artifacts/feed/dotnet-eng/NuGet/Microsoft.DotNet.Arcade.MSBuild.Xcopy/versions/17.12.0 - $defaultXCopyMSBuildVersion = '17.12.0' + # https://dev.azure.com/dnceng/public/_artifacts/feed/dotnet-eng/NuGet/Microsoft.DotNet.Arcade.MSBuild.Xcopy/versions/17.13.0 + $defaultXCopyMSBuildVersion = '17.13.0' if (!$vsRequirements) { if (Get-Member -InputObject $GlobalJson.tools -Name 'vs') { @@ -604,14 +602,7 @@ function InitializeBuildTool() { } $dotnetPath = Join-Path $dotnetRoot (GetExecutableFileName 'dotnet') - # Use override if it exists - commonly set by source-build - if ($null -eq $env:_OverrideArcadeInitializeBuildToolFramework) { - $initializeBuildToolFramework="net9.0" - } else { - $initializeBuildToolFramework=$env:_OverrideArcadeInitializeBuildToolFramework - } - - $buildTool = @{ Path = $dotnetPath; Command = 'msbuild'; Tool = 'dotnet'; Framework = $initializeBuildToolFramework } + $buildTool = @{ Path = $dotnetPath; Command = 'msbuild'; Tool = 'dotnet'; Framework = 'net' } } elseif ($msbuildEngine -eq "vs") { try { $msbuildPath = InitializeVisualStudioMSBuild -install:$restore @@ -620,7 +611,7 @@ function InitializeBuildTool() { ExitWithExitCode 1 } - $buildTool = @{ Path = $msbuildPath; Command = ""; Tool = "vs"; Framework = "net472"; ExcludePrereleaseVS = $excludePrereleaseVS } + $buildTool = @{ Path = $msbuildPath; Command = ""; Tool = "vs"; Framework = "netframework"; ExcludePrereleaseVS = $excludePrereleaseVS } } else { Write-PipelineTelemetryError -Category 'InitializeToolset' -Message "Unexpected value of -msbuildEngine: '$msbuildEngine'." ExitWithExitCode 1 @@ -653,7 +644,6 @@ function GetNuGetPackageCachePath() { $env:NUGET_PACKAGES = Join-Path $env:UserProfile '.nuget\packages\' } else { $env:NUGET_PACKAGES = Join-Path $RepoRoot '.packages\' - $env:RESTORENOHTTPCACHE = $true } } @@ -775,26 +765,13 @@ function MSBuild() { $toolsetBuildProject = InitializeToolset $basePath = Split-Path -parent $toolsetBuildProject - $possiblePaths = @( - # new scripts need to work with old packages, so we need to look for the old names/versions - (Join-Path $basePath (Join-Path $buildTool.Framework 'Microsoft.DotNet.ArcadeLogging.dll')), - (Join-Path $basePath (Join-Path $buildTool.Framework 'Microsoft.DotNet.Arcade.Sdk.dll')), - (Join-Path $basePath (Join-Path net7.0 'Microsoft.DotNet.ArcadeLogging.dll')), - (Join-Path $basePath (Join-Path net7.0 'Microsoft.DotNet.Arcade.Sdk.dll')), - (Join-Path $basePath (Join-Path net8.0 'Microsoft.DotNet.ArcadeLogging.dll')), - (Join-Path $basePath (Join-Path net8.0 'Microsoft.DotNet.Arcade.Sdk.dll')) - ) - $selectedPath = $null - foreach ($path in $possiblePaths) { - if (Test-Path $path -PathType Leaf) { - $selectedPath = $path - break - } - } + $selectedPath = Join-Path $basePath (Join-Path $buildTool.Framework 'Microsoft.DotNet.ArcadeLogging.dll') + if (-not $selectedPath) { - Write-PipelineTelemetryError -Category 'Build' -Message 'Unable to find arcade sdk logger assembly.' + Write-PipelineTelemetryError -Category 'Build' -Message "Unable to find arcade sdk logger assembly: $selectedPath" ExitWithExitCode 1 } + $args += "/logger:$selectedPath" } @@ -857,8 +834,8 @@ function MSBuild-Core() { } # When running on Azure Pipelines, override the returned exit code to avoid double logging. - # Skip this when the build is a child of the VMR orchestrator build. - if ($ci -and $env:SYSTEM_TEAMPROJECT -ne $null -and !$productBuild -and -not($properties -like "*DotNetBuildRepo=true*")) { + # Skip this when the build is a child of the VMR build. + if ($ci -and $env:SYSTEM_TEAMPROJECT -ne $null -and !$fromVMR) { Write-PipelineSetResult -Result "Failed" -Message "msbuild execution failed." # Exiting with an exit code causes the azure pipelines task to log yet another "noise" error # The above Write-PipelineSetResult will cause the task to be marked as failure without adding yet another error diff --git a/src/vstest/eng/common/tools.sh b/src/vstest/eng/common/tools.sh index 01b09b65796..3def02a638d 100644 --- a/src/vstest/eng/common/tools.sh +++ b/src/vstest/eng/common/tools.sh @@ -5,6 +5,9 @@ # CI mode - set to true on CI server for PR validation build or official build. ci=${ci:-false} +# Build mode +source_build=${source_build:-false} + # Set to true to use the pipelines logger which will enable Azure logging output. # https://github.com/Microsoft/azure-pipelines-tasks/blob/master/docs/authoring/commands.md # This flag is meant as a temporary opt-opt for the feature while validate it across @@ -58,7 +61,8 @@ use_installed_dotnet_cli=${use_installed_dotnet_cli:-true} dotnetInstallScriptVersion=${dotnetInstallScriptVersion:-'v1'} # True to use global NuGet cache instead of restoring packages to repository-local directory. -if [[ "$ci" == true ]]; then +# Keep in sync with NuGetPackageroot in Arcade SDK's RepositoryLayout.props. +if [[ "$ci" == true || "$source_build" == true ]]; then use_global_nuget_cache=${use_global_nuget_cache:-false} else use_global_nuget_cache=${use_global_nuget_cache:-true} @@ -68,8 +72,8 @@ fi runtime_source_feed=${runtime_source_feed:-''} runtime_source_feed_key=${runtime_source_feed_key:-''} -# True if the build is a product build -product_build=${product_build:-false} +# True when the build is running within the VMR. +from_vmr=${from_vmr:-false} # Resolve any symlinks in the given path. function ResolvePath { @@ -339,22 +343,14 @@ function InitializeBuildTool { # return values _InitializeBuildTool="$_InitializeDotNetCli/dotnet" _InitializeBuildToolCommand="msbuild" - # use override if it exists - commonly set by source-build - if [[ "${_OverrideArcadeInitializeBuildToolFramework:-x}" == "x" ]]; then - _InitializeBuildToolFramework="net9.0" - else - _InitializeBuildToolFramework="${_OverrideArcadeInitializeBuildToolFramework}" - fi } -# Set RestoreNoHttpCache as a workaround for https://github.com/NuGet/Home/issues/3116 function GetNuGetPackageCachePath { if [[ -z ${NUGET_PACKAGES:-} ]]; then if [[ "$use_global_nuget_cache" == true ]]; then export NUGET_PACKAGES="$HOME/.nuget/packages/" else export NUGET_PACKAGES="$repo_root/.packages/" - export RESTORENOHTTPCACHE=true fi fi @@ -451,25 +447,13 @@ function MSBuild { fi local toolset_dir="${_InitializeToolset%/*}" - # new scripts need to work with old packages, so we need to look for the old names/versions - local selectedPath= - local possiblePaths=() - possiblePaths+=( "$toolset_dir/$_InitializeBuildToolFramework/Microsoft.DotNet.ArcadeLogging.dll" ) - possiblePaths+=( "$toolset_dir/$_InitializeBuildToolFramework/Microsoft.DotNet.Arcade.Sdk.dll" ) - possiblePaths+=( "$toolset_dir/net7.0/Microsoft.DotNet.ArcadeLogging.dll" ) - possiblePaths+=( "$toolset_dir/net7.0/Microsoft.DotNet.Arcade.Sdk.dll" ) - possiblePaths+=( "$toolset_dir/net8.0/Microsoft.DotNet.ArcadeLogging.dll" ) - possiblePaths+=( "$toolset_dir/net8.0/Microsoft.DotNet.Arcade.Sdk.dll" ) - for path in "${possiblePaths[@]}"; do - if [[ -f $path ]]; then - selectedPath=$path - break - fi - done + local selectedPath="$toolset_dir/net/Microsoft.DotNet.ArcadeLogging.dll" + if [[ -z "$selectedPath" ]]; then - Write-PipelineTelemetryError -category 'Build' "Unable to find arcade sdk logger assembly." + Write-PipelineTelemetryError -category 'Build' "Unable to find arcade sdk logger assembly: $selectedPath" ExitWithExitCode 1 fi + args+=( "-logger:$selectedPath" ) fi @@ -506,8 +490,8 @@ function MSBuild-Core { echo "Build failed with exit code $exit_code. Check errors above." # When running on Azure Pipelines, override the returned exit code to avoid double logging. - # Skip this when the build is a child of the VMR orchestrator build. - if [[ "$ci" == true && -n ${SYSTEM_TEAMPROJECT:-} && "$product_build" != true && "$properties" != *"DotNetBuildRepo=true"* ]]; then + # Skip this when the build is a child of the VMR build. + if [[ "$ci" == true && -n ${SYSTEM_TEAMPROJECT:-} && "$from_vmr" != true ]]; then Write-PipelineSetResult -result "Failed" -message "msbuild execution failed." # Exiting with an exit code causes the azure pipelines task to log yet another "noise" error # The above Write-PipelineSetResult will cause the task to be marked as failure without adding yet another error @@ -530,6 +514,13 @@ function GetDarc { fi "$eng_root/common/darc-init.sh" --toolpath "$darc_path" $version + darc_tool="$darc_path/darc" +} + +# Returns a full path to an Arcade SDK task project file. +function GetSdkTaskProject { + taskName=$1 + echo "$(dirname $_InitializeToolset)/SdkTasks/$taskName.proj" } ResolvePath "${BASH_SOURCE[0]}" diff --git a/src/vstest/eng/common/vmr-sync.ps1 b/src/vstest/eng/common/vmr-sync.ps1 new file mode 100644 index 00000000000..97302f3205b --- /dev/null +++ b/src/vstest/eng/common/vmr-sync.ps1 @@ -0,0 +1,138 @@ +<# +.SYNOPSIS + +This script is used for synchronizing the current repository into a local VMR. +It pulls the current repository's code into the specified VMR directory for local testing or +Source-Build validation. + +.DESCRIPTION + +The tooling used for synchronization will clone the VMR repository into a temporary folder if +it does not already exist. These clones can be reused in future synchronizations, so it is +recommended to dedicate a folder for this to speed up re-runs. + +.EXAMPLE + Synchronize current repository into a local VMR: + ./vmr-sync.ps1 -vmrDir "$HOME/repos/dotnet" -tmpDir "$HOME/repos/tmp" + +.PARAMETER tmpDir +Required. Path to the temporary folder where repositories will be cloned + +.PARAMETER vmrBranch +Optional. Branch of the 'dotnet/dotnet' repo to synchronize. The VMR will be checked out to this branch + +.PARAMETER azdevPat +Optional. Azure DevOps PAT to use for cloning private repositories. + +.PARAMETER vmrDir +Optional. Path to the dotnet/dotnet repository. When null, gets cloned to the temporary folder + +.PARAMETER debugOutput +Optional. Enables debug logging in the darc vmr command. + +.PARAMETER ci +Optional. Denotes that the script is running in a CI environment. +#> +param ( + [Parameter(Mandatory=$true, HelpMessage="Path to the temporary folder where repositories will be cloned")] + [string][Alias('t', 'tmp')]$tmpDir, + [string][Alias('b', 'branch')]$vmrBranch, + [string]$remote, + [string]$azdevPat, + [string][Alias('v', 'vmr')]$vmrDir, + [switch]$ci, + [switch]$debugOutput +) + +function Fail { + Write-Host "> $($args[0])" -ForegroundColor 'Red' +} + +function Highlight { + Write-Host "> $($args[0])" -ForegroundColor 'Cyan' +} + +$verbosity = 'verbose' +if ($debugOutput) { + $verbosity = 'debug' +} +# Validation + +if (-not $tmpDir) { + Fail "Missing -tmpDir argument. Please specify the path to the temporary folder where the repositories will be cloned" + exit 1 +} + +# Sanitize the input + +if (-not $vmrDir) { + $vmrDir = Join-Path $tmpDir 'dotnet' +} + +if (-not (Test-Path -Path $tmpDir -PathType Container)) { + New-Item -ItemType Directory -Path $tmpDir | Out-Null +} + +# Prepare the VMR + +if (-not (Test-Path -Path $vmrDir -PathType Container)) { + Highlight "Cloning 'dotnet/dotnet' into $vmrDir.." + git clone https://github.com/dotnet/dotnet $vmrDir + + if ($vmrBranch) { + git -C $vmrDir switch -c $vmrBranch + } +} +else { + if ((git -C $vmrDir diff --quiet) -eq $false) { + Fail "There are changes in the working tree of $vmrDir. Please commit or stash your changes" + exit 1 + } + + if ($vmrBranch) { + Highlight "Preparing $vmrDir" + git -C $vmrDir checkout $vmrBranch + git -C $vmrDir pull + } +} + +Set-StrictMode -Version Latest + +# Prepare darc + +Highlight 'Installing .NET, preparing the tooling..' +. .\eng\common\tools.ps1 +$dotnetRoot = InitializeDotNetCli -install:$true +$darc = Get-Darc +$dotnet = "$dotnetRoot\dotnet.exe" + +Highlight "Starting the synchronization of VMR.." + +# Synchronize the VMR +$darcArgs = ( + "vmr", "forwardflow", + "--tmp", $tmpDir, + "--$verbosity", + $vmrDir +) + +if ($ci) { + $darcArgs += ("--ci") +} + +if ($azdevPat) { + $darcArgs += ("--azdev-pat", $azdevPat) +} + +& "$darc" $darcArgs + +if ($LASTEXITCODE -eq 0) { + Highlight "Synchronization succeeded" +} +else { + Fail "Synchronization of repo to VMR failed!" + Fail "'$vmrDir' is left in its last state (re-run of this script will reset it)." + Fail "Please inspect the logs which contain path to the failing patch file (use -debugOutput to get all the details)." + Fail "Once you make changes to the conflicting VMR patch, commit it locally and re-run this script." + exit 1 +} diff --git a/src/vstest/eng/common/vmr-sync.sh b/src/vstest/eng/common/vmr-sync.sh new file mode 100644 index 00000000000..44239e331c0 --- /dev/null +++ b/src/vstest/eng/common/vmr-sync.sh @@ -0,0 +1,207 @@ +#!/bin/bash + +### This script is used for synchronizing the current repository into a local VMR. +### It pulls the current repository's code into the specified VMR directory for local testing or +### Source-Build validation. +### +### The tooling used for synchronization will clone the VMR repository into a temporary folder if +### it does not already exist. These clones can be reused in future synchronizations, so it is +### recommended to dedicate a folder for this to speed up re-runs. +### +### USAGE: +### Synchronize current repository into a local VMR: +### ./vmr-sync.sh --tmp "$HOME/repos/tmp" "$HOME/repos/dotnet" +### +### Options: +### -t, --tmp, --tmp-dir PATH +### Required. Path to the temporary folder where repositories will be cloned +### +### -b, --branch, --vmr-branch BRANCH_NAME +### Optional. Branch of the 'dotnet/dotnet' repo to synchronize. The VMR will be checked out to this branch +### +### --debug +### Optional. Turns on the most verbose logging for the VMR tooling +### +### --remote name:URI +### Optional. Additional remote to use during the synchronization +### This can be used to synchronize to a commit from a fork of the repository +### Example: 'runtime:https://github.com/yourfork/runtime' +### +### --azdev-pat +### Optional. Azure DevOps PAT to use for cloning private repositories. +### +### -v, --vmr, --vmr-dir PATH +### Optional. Path to the dotnet/dotnet repository. When null, gets cloned to the temporary folder + +source="${BASH_SOURCE[0]}" + +# resolve $source until the file is no longer a symlink +while [[ -h "$source" ]]; do + scriptroot="$( cd -P "$( dirname "$source" )" && pwd )" + source="$(readlink "$source")" + # if $source was a relative symlink, we need to resolve it relative to the path where the + # symlink file was located + [[ $source != /* ]] && source="$scriptroot/$source" +done +scriptroot="$( cd -P "$( dirname "$source" )" && pwd )" + +function print_help () { + sed -n '/^### /,/^$/p' "$source" | cut -b 5- +} + +COLOR_RED=$(tput setaf 1 2>/dev/null || true) +COLOR_CYAN=$(tput setaf 6 2>/dev/null || true) +COLOR_CLEAR=$(tput sgr0 2>/dev/null || true) +COLOR_RESET=uniquesearchablestring +FAILURE_PREFIX='> ' + +function fail () { + echo "${COLOR_RED}$FAILURE_PREFIX${1//${COLOR_RESET}/${COLOR_RED}}${COLOR_CLEAR}" >&2 +} + +function highlight () { + echo "${COLOR_CYAN}$FAILURE_PREFIX${1//${COLOR_RESET}/${COLOR_CYAN}}${COLOR_CLEAR}" +} + +tmp_dir='' +vmr_dir='' +vmr_branch='' +additional_remotes='' +verbosity=verbose +azdev_pat='' +ci=false + +while [[ $# -gt 0 ]]; do + opt="$(echo "$1" | tr "[:upper:]" "[:lower:]")" + case "$opt" in + -t|--tmp|--tmp-dir) + tmp_dir=$2 + shift + ;; + -v|--vmr|--vmr-dir) + vmr_dir=$2 + shift + ;; + -b|--branch|--vmr-branch) + vmr_branch=$2 + shift + ;; + --remote) + additional_remotes="$additional_remotes $2" + shift + ;; + --azdev-pat) + azdev_pat=$2 + shift + ;; + --ci) + ci=true + ;; + -d|--debug) + verbosity=debug + ;; + -h|--help) + print_help + exit 0 + ;; + *) + fail "Invalid argument: $1" + print_help + exit 1 + ;; + esac + + shift +done + +# Validation + +if [[ -z "$tmp_dir" ]]; then + fail "Missing --tmp-dir argument. Please specify the path to the temporary folder where the repositories will be cloned" + exit 1 +fi + +# Sanitize the input + +if [[ -z "$vmr_dir" ]]; then + vmr_dir="$tmp_dir/dotnet" +fi + +if [[ ! -d "$tmp_dir" ]]; then + mkdir -p "$tmp_dir" +fi + +if [[ "$verbosity" == "debug" ]]; then + set -x +fi + +# Prepare the VMR + +if [[ ! -d "$vmr_dir" ]]; then + highlight "Cloning 'dotnet/dotnet' into $vmr_dir.." + git clone https://github.com/dotnet/dotnet "$vmr_dir" + + if [[ -n "$vmr_branch" ]]; then + git -C "$vmr_dir" switch -c "$vmr_branch" + fi +else + if ! git -C "$vmr_dir" diff --quiet; then + fail "There are changes in the working tree of $vmr_dir. Please commit or stash your changes" + exit 1 + fi + + if [[ -n "$vmr_branch" ]]; then + highlight "Preparing $vmr_dir" + git -C "$vmr_dir" checkout "$vmr_branch" + git -C "$vmr_dir" pull + fi +fi + +set -e + +# Prepare darc + +highlight 'Installing .NET, preparing the tooling..' +source "./eng/common/tools.sh" +InitializeDotNetCli true +GetDarc +dotnetDir=$( cd ./.dotnet/; pwd -P ) +dotnet=$dotnetDir/dotnet + +highlight "Starting the synchronization of VMR.." +set +e + +if [[ -n "$additional_remotes" ]]; then + additional_remotes="--additional-remotes $additional_remotes" +fi + +if [[ -n "$azdev_pat" ]]; then + azdev_pat="--azdev-pat $azdev_pat" +fi + +ci_arg='' +if [[ "$ci" == "true" ]]; then + ci_arg="--ci" +fi + +# Synchronize the VMR + +export DOTNET_ROOT="$dotnetDir" + +"$darc_tool" vmr forwardflow \ + --tmp "$tmp_dir" \ + $azdev_pat \ + --$verbosity \ + $ci_arg \ + $additional_remotes \ + "$vmr_dir" + +if [[ $? == 0 ]]; then + highlight "Synchronization succeeded" +else + fail "Synchronization of repo to VMR failed!" + fail "'$vmr_dir' is left in its last state (re-run of this script will reset it)." + fail "Please inspect the logs which contain path to the failing patch file (use --debug to get all the details)." + fail "Once you make changes to the conflicting VMR patch, commit it locally and re-run this script." + exit 1 +fi diff --git a/src/vstest/eng/verify-nupkgs.ps1 b/src/vstest/eng/verify-nupkgs.ps1 index f1595e100f2..1d571723de0 100644 --- a/src/vstest/eng/verify-nupkgs.ps1 +++ b/src/vstest/eng/verify-nupkgs.ps1 @@ -17,9 +17,9 @@ Add-Type -AssemblyName System.IO.Compression.FileSystem function Verify-Nuget-Packages { Write-Host "Starting Verify-Nuget-Packages." $expectedNumOfFiles = @{ - "Microsoft.CodeCoverage" = 59; + "Microsoft.CodeCoverage" = 75; "Microsoft.NET.Test.Sdk" = 25; - "Microsoft.TestPlatform" = 619; + "Microsoft.TestPlatform" = 601; "Microsoft.TestPlatform.Build" = 20; "Microsoft.TestPlatform.CLI" = 481; "Microsoft.TestPlatform.Extensions.TrxLogger" = 34; diff --git a/src/vstest/global.json b/src/vstest/global.json index ae9cab826fc..ed7ad0de933 100644 --- a/src/vstest/global.json +++ b/src/vstest/global.json @@ -1,6 +1,6 @@ { "sdk": { - "version": "9.0.106", + "version": "10.0.100-preview.6.25315.102", "rollForward": "minor", "allowPrerelease": false, "architecture": "x64" @@ -13,7 +13,8 @@ "5.0.17", "6.0.32", "7.0.20", - "8.0.7" + "8.0.7", + "9.0.5" ], "dotnet/x86": [ "2.1.30", @@ -21,16 +22,17 @@ "5.0.17", "6.0.32", "7.0.20", - "8.0.7" + "8.0.7", + "9.0.5" ] }, "vs": { "version": "17.8.0" }, "vswhere": "2.2.7", - "dotnet": "9.0.106" + "dotnet": "10.0.100-preview.6.25315.102" }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "9.0.0-beta.25302.2" + "Microsoft.DotNet.Arcade.Sdk": "10.0.0-beta.25358.3" } } diff --git a/src/vstest/playground/TestPlatform.Playground/TestPlatform.Playground.csproj b/src/vstest/playground/TestPlatform.Playground/TestPlatform.Playground.csproj index 620c160e2db..7259dc0728d 100644 --- a/src/vstest/playground/TestPlatform.Playground/TestPlatform.Playground.csproj +++ b/src/vstest/playground/TestPlatform.Playground/TestPlatform.Playground.csproj @@ -4,6 +4,14 @@ None $(MSBuildWarningsAsMessages);MSB3276 + + false + + false @@ -12,8 +20,8 @@ - - + + @@ -56,8 +64,8 @@ - - + + diff --git a/src/vstest/src/Microsoft.TestPlatform.Common/ExternalAssemblyVersions.cs b/src/vstest/src/Microsoft.TestPlatform.Common/ExternalAssemblyVersions.cs index 7e831df12f2..f05cf8adc33 100644 --- a/src/vstest/src/Microsoft.TestPlatform.Common/ExternalAssemblyVersions.cs +++ b/src/vstest/src/Microsoft.TestPlatform.Common/ExternalAssemblyVersions.cs @@ -10,5 +10,5 @@ internal class ExternalAssemblyVersions /// Microsoft.QualityTools.Testing.Fakes.TestRunnerHarness package. /// The Package version can be found in "eng\Versions.props" /// - internal const string MicrosoftFakesAssemblyVersion = "17.0.0.0"; + internal const string MicrosoftFakesAssemblyVersion = "18.0.0.0"; } diff --git a/src/vstest/src/Microsoft.TestPlatform.TestHostProvider/Hosting/DotnetTestHostManager.cs b/src/vstest/src/Microsoft.TestPlatform.TestHostProvider/Hosting/DotnetTestHostManager.cs index a20519373bb..5845c7b3b32 100644 --- a/src/vstest/src/Microsoft.TestPlatform.TestHostProvider/Hosting/DotnetTestHostManager.cs +++ b/src/vstest/src/Microsoft.TestPlatform.TestHostProvider/Hosting/DotnetTestHostManager.cs @@ -513,23 +513,115 @@ public virtual TestProcessStartInfo GetTestHostProcessStartInfo( // i.e. I've got only private install and no global installation, in this case apphost needs to use env var to locate runtime. if (testHostExeFound) { - string prefix = "VSTEST_WINAPPHOST_"; - string dotnetRootEnvName = $"{prefix}DOTNET_ROOT(x86)"; - var dotnetRoot = _environmentVariableHelper.GetEnvironmentVariable(dotnetRootEnvName); - if (dotnetRoot is null) + // This change needs to happen first on vstest side, and then on dotnet/sdk, so prefer this approach and fallback to the old one. + // VSTEST_DOTNET_ROOT v2 + string? dotnetRootPath = _environmentVariableHelper.GetEnvironmentVariable("VSTEST_DOTNET_ROOT_PATH"); + if (!StringUtils.IsNullOrWhiteSpace(dotnetRootPath)) { - dotnetRootEnvName = $"{prefix}DOTNET_ROOT"; - dotnetRoot = _environmentVariableHelper.GetEnvironmentVariable(dotnetRootEnvName); - } + // This is v2 of the environment variables that we are passing, we are in new dotnet sdk. So also grab the architecture. + string? dotnetRootArchitecture = _environmentVariableHelper.GetEnvironmentVariable("VSTEST_DOTNET_ROOT_ARCHITECTURE"); - if (dotnetRoot != null) - { - EqtTrace.Verbose($"DotnetTestHostmanager.LaunchTestHostAsync: Found '{dotnetRootEnvName}' in env variables, value '{dotnetRoot}', forwarding to '{dotnetRootEnvName.Replace(prefix, string.Empty)}'"); - startInfo.EnvironmentVariables.Add(dotnetRootEnvName.Replace(prefix, string.Empty), dotnetRoot); + if (StringUtils.IsNullOrWhiteSpace(dotnetRootArchitecture)) + { + throw new InvalidOperationException("'VSTEST_DOTNET_ROOT_PATH' and 'VSTEST_DOTNET_ROOT_ARCHITECTURE' must be both always set. If you are seeing this error, this is a bug in dotnet SDK that sets those variables."); + } + + EqtTrace.Verbose($"DotnetTestHostmanager.LaunchTestHostAsync: VSTEST_DOTNET_ROOT_PATH={dotnetRootPath}"); + EqtTrace.Verbose($"DotnetTestHostmanager.LaunchTestHostAsync: VSTEST_DOTNET_ROOT_ARCHITECTURE={dotnetRootArchitecture}"); + + // The parent process is passing to us the path in which the dotnet.exe is and is passing the architecture of the dotnet.exe, + // so if the child process (testhost) is the same architecture it can pick up that dotnet.exe location and run. This is to allow + // local installations of dotnet/sdk to work with testhost. + // + // There are 2 complications in this process: + // 1) There are differences between how .NET Apphosts are handling DOTNET_ROOT, versions pre-net6 are only looking at + // DOTNET_ROOT(x86) and then DOTNET_ROOT. This makes is really easy to set DOTNET_ROOT to point at x64 dotnet installation + // and have that picked up by x86 testhost and fail. + // Unfortunately vstest.console has to support both new (17.14+) testhosts that are built against net8, and old (pre 17.14) + // testhosts that are built using netcoreapp3.1 apphost, and so their approach to resolving DOTNET_ROOT differ. + // + // /!\ The apphost version does not align with the targeted framework (tfm), an older testhost is built against netcoreapp3.1 + // but can be used to run net8 tests. The only way to tell is the version of the testhost. + // + // netcoreapp3.1 hosts only support DOTNET_ROOT and DOTNET_ROOT(x86) env variables. + // net8 hosts, support also DOTNET_ROOT_ variables, which is what we should prefer to set the location of dotnet + // in a more architecture specific way. + // + // 2) The surrounding environment might already have the environment variables set, most likely by setting DOTNET_ROOT, which is + // a universal way of setting where the dotnet is, that works across all different architectures of the .NET apphost. + // By setting our (hopefully more specific variable) we might overwrite what user specified, and in case of DOTNET_ROOT it is probably + // preferable when we can set the DOTNET_ROOT_ variable. + var testhostDllPath = Path.ChangeExtension(startInfo.FileName, ".dll"); + // This file check is for unit tests, we expect the file to always be there. Otherwise testhost.exe would not be able to run. + var testhostVersionInfo = _fileHelper.Exists(testhostDllPath) ? FileVersionInfo.GetVersionInfo(testhostDllPath) : null; + if (testhostVersionInfo != null && testhostVersionInfo.ProductMajorPart >= 17 && testhostVersionInfo.ProductMinorPart >= 14) + { + // This is a new testhost that builds at least against net8 we should set the architecture specific DOTNET_ROOT_. + // + // We ship just testhost.exe and testhost.x86.exe if the architecture is different we won't find the testhost*.exe and + // won't reach this code, but let's write this in a generic way anyway, to avoid breaking if we add more variants of testhost*.exe. + var environmentVariableName = $"DOTNET_ROOT_{_architecture.ToString().ToUpperInvariant()}"; + + var existingDotnetRoot = _environmentVariableHelper.GetEnvironmentVariable(environmentVariableName); + if (!StringUtilities.IsNullOrWhiteSpace(existingDotnetRoot)) + { + // The variable is already set in the surrounding environment, don't set it, because we want to keep what user provided. + } + else + { + // Set the architecture specific variable to the environment of the process so it is picked up. + startInfo.EnvironmentVariables.Add(environmentVariableName, dotnetRootPath); + } + } + else + { + // This is an old testhost that built against netcoreapp3.1, it does not understand architecture specific DOTNET_ROOT_, we have to set it more carefully + // to avoid setting DOTNET_ROOT that points to x64 but is picked up by x86 host. + // + // Also avoid setting it if we are already getting it from the surrounding environment. + var architectureFromEnv = (Architecture)Enum.Parse(typeof(Architecture), dotnetRootArchitecture, ignoreCase: true); + if (architectureFromEnv == _architecture) + { + if (_architecture == Architecture.X86) + { + const string dotnetRootX86 = "DOTNET_ROOT(x86)"; + if (StringUtils.IsNullOrWhiteSpace(_environmentVariableHelper.GetEnvironmentVariable(dotnetRootX86))) + { + startInfo.EnvironmentVariables.Add(dotnetRootX86, dotnetRootPath); + } + } + else + { + const string dotnetRoot = "DOTNET_ROOT"; + if (StringUtils.IsNullOrWhiteSpace(_environmentVariableHelper.GetEnvironmentVariable(dotnetRoot))) + { + startInfo.EnvironmentVariables.Add(dotnetRoot, dotnetRootPath); + } + } + } + } } else { - EqtTrace.Verbose($"DotnetTestHostmanager.LaunchTestHostAsync: Prefix '{prefix}*' not found in env variables"); + // Fallback, can delete this once the change is in dotnet sdk. because they are always used together. + string prefix = "VSTEST_WINAPPHOST_"; + string dotnetRootEnvName = $"{prefix}DOTNET_ROOT(x86)"; + var dotnetRoot = _environmentVariableHelper.GetEnvironmentVariable(dotnetRootEnvName); + if (dotnetRoot is null) + { + dotnetRootEnvName = $"{prefix}DOTNET_ROOT"; + dotnetRoot = _environmentVariableHelper.GetEnvironmentVariable(dotnetRootEnvName); + } + + if (dotnetRoot != null) + { + EqtTrace.Verbose($"DotnetTestHostmanager.LaunchTestHostAsync: Found '{dotnetRootEnvName}' in env variables, value '{dotnetRoot}', forwarding to '{dotnetRootEnvName.Replace(prefix, string.Empty)}'"); + startInfo.EnvironmentVariables.Add(dotnetRootEnvName.Replace(prefix, string.Empty), dotnetRoot); + } + else + { + EqtTrace.Verbose($"DotnetTestHostmanager.LaunchTestHostAsync: Prefix '{prefix}*' not found in env variables"); + } } } diff --git a/src/vstest/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/VsTestConsoleRequestSender.cs b/src/vstest/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/VsTestConsoleRequestSender.cs index e72355cd5b2..4c623ed472d 100644 --- a/src/vstest/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/VsTestConsoleRequestSender.cs +++ b/src/vstest/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/VsTestConsoleRequestSender.cs @@ -1197,7 +1197,7 @@ private void SendMessageAndListenAndReportTestResults( EqtTrace.Error("Aborting Test Run Operation: {0}", exception); eventHandler.HandleLogMessage( TestMessageLevel.Error, - TranslationLayerResources.AbortedTestsRun); + TranslationLayerResources.AbortedTestsRun + " " + exception.ToString()); var completeArgs = new TestRunCompleteEventArgs( null, false, true, exception, null, null, TimeSpan.Zero); eventHandler.HandleTestRunComplete(completeArgs, null, null, null); @@ -1282,7 +1282,7 @@ private async Task SendMessageAndListenAndReportTestResultsAsync( EqtTrace.Error("Aborting Test Run Operation: {0}", exception); eventHandler.HandleLogMessage( TestMessageLevel.Error, - TranslationLayerResources.AbortedTestsRun); + TranslationLayerResources.AbortedTestsRun + " " + exception.ToString()); var completeArgs = new TestRunCompleteEventArgs( null, false, true, exception, null, null, TimeSpan.Zero); eventHandler.HandleTestRunComplete(completeArgs, null, null, null); diff --git a/src/vstest/src/package/Microsoft.CodeCoverage/Microsoft.CodeCoverage.csproj b/src/vstest/src/package/Microsoft.CodeCoverage/Microsoft.CodeCoverage.csproj index 64ed693b4ca..11f305b2150 100644 --- a/src/vstest/src/package/Microsoft.CodeCoverage/Microsoft.CodeCoverage.csproj +++ b/src/vstest/src/package/Microsoft.CodeCoverage/Microsoft.CodeCoverage.csproj @@ -1,4 +1,4 @@ - + - - - - - - - - - - - - - + diff --git a/src/vstest/src/package/Microsoft.TestPlatform/Microsoft.TestPlatform.csproj b/src/vstest/src/package/Microsoft.TestPlatform/Microsoft.TestPlatform.csproj index 46ebe5d69b1..194eac7e864 100644 --- a/src/vstest/src/package/Microsoft.TestPlatform/Microsoft.TestPlatform.csproj +++ b/src/vstest/src/package/Microsoft.TestPlatform/Microsoft.TestPlatform.csproj @@ -1,4 +1,4 @@ - + $(TestHostAllTargetFrameworks) @@ -25,12 +25,6 @@ This package contains the full set of binaries for the Visual Studio Test Platform (vstest). It provides a modern, cross platform testing engine that powers the testing on .NET Core as well. It integrates with popular test frameworks like MSTest(v1 and v2), xUnit and Nunit with support for extensibility. - - The package supports running Coded UI tests. - While running Coded UI tests, you must ensure that the package version matches the major version of Visual Studio used to build the test binaries. - For example, if your Coded UI test project was built using Visual Studio 2019 (version 16.x), you must use test platform version 16.x. - Coded UI test is deprecated (https://docs.microsoft.com/en-us/visualstudio/releases/2019/release-notes-preview#test-tools) and - Visual Studio 2019 (Test Platform version 16.x) will be the last version with Coded UI test functionality. LICENSE_VS.txt @@ -83,8 +77,6 @@ --> - - @@ -102,7 +94,6 @@ - @@ -111,7 +102,6 @@ - @@ -127,8 +117,7 @@ - - + @@ -136,7 +125,6 @@ - @@ -152,7 +140,6 @@ - diff --git a/src/vstest/src/package/Microsoft.TestPlatform/Microsoft.TestPlatform.nuspec b/src/vstest/src/package/Microsoft.TestPlatform/Microsoft.TestPlatform.nuspec index a2e27146bc1..75cdafdd6bd 100644 --- a/src/vstest/src/package/Microsoft.TestPlatform/Microsoft.TestPlatform.nuspec +++ b/src/vstest/src/package/Microsoft.TestPlatform/Microsoft.TestPlatform.nuspec @@ -58,8 +58,6 @@ - - @@ -98,8 +96,6 @@ - - @@ -238,29 +234,6 @@ - - - - - - - - - - - - - - - - - - - - - - - @@ -426,7 +399,6 @@ - @@ -457,59 +429,12 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + diff --git a/src/vstest/src/package/Microsoft.VisualStudio.TestTools.TestPlatform.V2.CLI/Microsoft.VisualStudio.TestTools.TestPlatform.V2.CLI.csproj b/src/vstest/src/package/Microsoft.VisualStudio.TestTools.TestPlatform.V2.CLI/Microsoft.VisualStudio.TestTools.TestPlatform.V2.CLI.csproj index bf5410cb19e..428a98d2e7a 100644 --- a/src/vstest/src/package/Microsoft.VisualStudio.TestTools.TestPlatform.V2.CLI/Microsoft.VisualStudio.TestTools.TestPlatform.V2.CLI.csproj +++ b/src/vstest/src/package/Microsoft.VisualStudio.TestTools.TestPlatform.V2.CLI/Microsoft.VisualStudio.TestTools.TestPlatform.V2.CLI.csproj @@ -31,7 +31,6 @@ $(ArtifactsBinDir)Microsoft.TestPlatform.CLI\$(Configuration)\$(NetFrameworkMinimum)\ $(ArtifactsBinDir)Microsoft.TestPlatform\$(Configuration)\$(NetFrameworkRunnerTargetFramework)\ $(TestPlatformBinFolder)Microsoft.Internal.Dia\ - $(TestPlatformBinFolder)Microsoft.VisualStudio.CUIT\ $(TestPlatformBinFolder)Microsoft.CodeCoverage.IO\ $(TestPlatformBinFolder)Microsoft.VisualStudio.QualityTools\ $(TestPlatformBinFolder)Microsoft.Extensions.DependencyModel\ @@ -141,25 +140,6 @@ - - - - CUITPlugins - - - CUITPlugins - - - - - - - - - - - - diff --git a/src/vstest/src/testhost.x86/app.config b/src/vstest/src/testhost.x86/app.config index 80f1fde9297..b06017b279b 100644 --- a/src/vstest/src/testhost.x86/app.config +++ b/src/vstest/src/testhost.x86/app.config @@ -18,7 +18,7 @@ - + @@ -26,23 +26,23 @@ - + - + - + - + - + diff --git a/src/vstest/src/vstest.console/TestPlatformHelpers/TestRequestManager.cs b/src/vstest/src/vstest.console/TestPlatformHelpers/TestRequestManager.cs index f93857b671b..63f8d99c09c 100644 --- a/src/vstest/src/vstest.console/TestPlatformHelpers/TestRequestManager.cs +++ b/src/vstest/src/vstest.console/TestPlatformHelpers/TestRequestManager.cs @@ -1600,6 +1600,7 @@ internal static class KnownPlatformSourceFilter "Microsoft.Testing.Extensions.HangDump.resources.dll", "Microsoft.Testing.Extensions.HotReload.dll", "Microsoft.Testing.Extensions.HotReload.resources.dll", + "Microsoft.Testing.Extensions.MSBuild.dll", "Microsoft.Testing.Extensions.Retry.dll", "Microsoft.Testing.Extensions.Retry.resources.dll", "Microsoft.Testing.Extensions.Telemetry.dll", diff --git a/src/vstest/src/vstest.console/app.config b/src/vstest/src/vstest.console/app.config index bd074de580e..3f040b9d206 100644 --- a/src/vstest/src/vstest.console/app.config +++ b/src/vstest/src/vstest.console/app.config @@ -14,11 +14,11 @@ - + - + diff --git a/src/vstest/test/DataCollectors/Microsoft.TestPlatform.Extensions.EventLogCollector.UnitTests/Microsoft.TestPlatform.Extensions.EventLogCollector.UnitTests.csproj b/src/vstest/test/DataCollectors/Microsoft.TestPlatform.Extensions.EventLogCollector.UnitTests/Microsoft.TestPlatform.Extensions.EventLogCollector.UnitTests.csproj index d0bf3ef5c38..3d675a513fd 100644 --- a/src/vstest/test/DataCollectors/Microsoft.TestPlatform.Extensions.EventLogCollector.UnitTests/Microsoft.TestPlatform.Extensions.EventLogCollector.UnitTests.csproj +++ b/src/vstest/test/DataCollectors/Microsoft.TestPlatform.Extensions.EventLogCollector.UnitTests/Microsoft.TestPlatform.Extensions.EventLogCollector.UnitTests.csproj @@ -5,6 +5,7 @@ true false + Exe diff --git a/src/vstest/test/Directory.Build.props b/src/vstest/test/Directory.Build.props index 6f5b8d7bf3c..b93c6783d24 100644 --- a/src/vstest/test/Directory.Build.props +++ b/src/vstest/test/Directory.Build.props @@ -3,5 +3,16 @@ true + true + + true + + + + diff --git a/src/vstest/test/Microsoft.TestPlatform.Acceptance.IntegrationTests/.runsettings b/src/vstest/test/Microsoft.TestPlatform.Acceptance.IntegrationTests/.runsettings new file mode 100644 index 00000000000..823b5bb2d55 --- /dev/null +++ b/src/vstest/test/Microsoft.TestPlatform.Acceptance.IntegrationTests/.runsettings @@ -0,0 +1,5 @@ + + + true + + \ No newline at end of file diff --git a/src/vstest/test/Microsoft.TestPlatform.Acceptance.IntegrationTests/Build.cs b/src/vstest/test/Microsoft.TestPlatform.Acceptance.IntegrationTests/Build.cs index 8fab97215f8..8dd581b00ff 100644 --- a/src/vstest/test/Microsoft.TestPlatform.Acceptance.IntegrationTests/Build.cs +++ b/src/vstest/test/Microsoft.TestPlatform.Acceptance.IntegrationTests/Build.cs @@ -62,7 +62,17 @@ private static void CopyAndPatchDotnet() // e.g. artifacts\tmp\.dotnet\sdk\ var sdkDirectory = Path.Combine(patchedDotnetDir, "sdk"); // e.g. artifacts\tmp\.dotnet\sdk\8.0.100-preview.6.23330.14 - var dotnetSdkDirectory = Directory.GetDirectories(sdkDirectory).Single(); + var dotnetSdkDirectories = Directory.GetDirectories(sdkDirectory); + if (dotnetSdkDirectories.Length == 0) + { + throw new InvalidOperationException($"No .NET SDK directories found in '{sdkDirectory}'."); + } + if (dotnetSdkDirectories.Length > 1) + { + throw new InvalidOperationException($"More than 1 .NET SDK directories found in '{sdkDirectory}': {string.Join(", ", dotnetSdkDirectories)}."); + } + + var dotnetSdkDirectory = dotnetSdkDirectories.Single(); DirectoryUtils.CopyDirectory(Path.Combine(packagePath, "lib", "netstandard2.0"), dotnetSdkDirectory); DirectoryUtils.CopyDirectory(Path.Combine(packagePath, "runtimes", "any", "native"), dotnetSdkDirectory); } diff --git a/src/vstest/test/Microsoft.TestPlatform.Acceptance.IntegrationTests/CUITTest.cs b/src/vstest/test/Microsoft.TestPlatform.Acceptance.IntegrationTests/CUITTest.cs deleted file mode 100644 index 96f8da27c67..00000000000 --- a/src/vstest/test/Microsoft.TestPlatform.Acceptance.IntegrationTests/CUITTest.cs +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using Microsoft.TestPlatform.TestUtilities; -using Microsoft.VisualStudio.TestTools.UnitTesting; - -namespace Microsoft.TestPlatform.AcceptanceTests; - -[TestClass] -[TestCategory("Windows-Review")] -public class CuitTest : AcceptanceTestBase -{ - [TestMethod] - [TestCategory("Windows-Review")] - [NetFullTargetFrameworkDataSource] - public void CuitRunAllTests(RunnerInfo runnerInfo) - { - SetTestEnvironment(_testEnvironment, runnerInfo); - CuitRunAll(runnerInfo); - } - - private void CuitRunAll(RunnerInfo runnerInfo) - { - if (runnerInfo.IsNetRunner) - { - Assert.Inconclusive("CUIT tests are not supported with .NET Core runner."); - return; - } - - var assemblyAbsolutePath = _testEnvironment.GetTestAsset("CUITTestProject.dll", "net462"); - var arguments = PrepareArguments(assemblyAbsolutePath, string.Empty, string.Empty, FrameworkArgValue, resultsDirectory: TempDirectory.Path); - arguments += " -- RunConfiguration.TargetPlatform=x86"; - - InvokeVsTest(arguments); - ValidateSummaryStatus(1, 0, 0); - } -} diff --git a/src/vstest/test/Microsoft.TestPlatform.Acceptance.IntegrationTests/DotnetTestMSBuildOutputTests.cs b/src/vstest/test/Microsoft.TestPlatform.Acceptance.IntegrationTests/DotnetTestMSBuildOutputTests.cs index 3aca6e7e04f..995ee1e133b 100644 --- a/src/vstest/test/Microsoft.TestPlatform.Acceptance.IntegrationTests/DotnetTestMSBuildOutputTests.cs +++ b/src/vstest/test/Microsoft.TestPlatform.Acceptance.IntegrationTests/DotnetTestMSBuildOutputTests.cs @@ -2,6 +2,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System.Collections.Generic; +using System.IO; using Microsoft.TestPlatform.TestUtilities; using Microsoft.VisualStudio.TestTools.UnitTesting; @@ -24,7 +25,7 @@ public void MSBuildLoggerCanBeEnabledByBuildPropertyAndDoesNotEatSpecialChars(Ru var projectPath = GetIsolatedTestAsset("TerminalLoggerTestProject.csproj"); // Forcing terminal logger so we can see the output when it is redirected - InvokeDotnetTest($@"{projectPath} -tl:on -nodereuse:false /p:PackageVersion={IntegrationTestEnvironment.LatestLocallyBuiltNugetVersion}"); + InvokeDotnetTest($@"{projectPath} -tl:on -nodereuse:false /p:PackageVersion={IntegrationTestEnvironment.LatestLocallyBuiltNugetVersion}", workingDirectory: Path.GetDirectoryName(projectPath)); // The output: // Determining projects to restore... @@ -53,7 +54,7 @@ public void MSBuildLoggerCanBeDisabledByBuildProperty(RunnerInfo runnerInfo) SetTestEnvironment(_testEnvironment, runnerInfo); var projectPath = GetIsolatedTestAsset("TerminalLoggerTestProject.csproj"); - InvokeDotnetTest($@"{projectPath} -nodereuse:false /p:VsTestUseMSBuildOutput=false /p:PackageVersion={IntegrationTestEnvironment.LatestLocallyBuiltNugetVersion}"); + InvokeDotnetTest($@"{projectPath} -nodereuse:false /p:VsTestUseMSBuildOutput=false /p:PackageVersion={IntegrationTestEnvironment.LatestLocallyBuiltNugetVersion}", workingDirectory: Path.GetDirectoryName(projectPath)); // Check that we see the summary that is printed from the console logger, meaning the new output is disabled. StdOutputContains("Failed! - Failed: 1, Passed: 1, Skipped: 1, Total: 3, Duration:"); @@ -73,7 +74,7 @@ public void MSBuildLoggerCanBeDisabledByEnvironmentVariableProperty(RunnerInfo r SetTestEnvironment(_testEnvironment, runnerInfo); var projectPath = GetIsolatedTestAsset("TerminalLoggerTestProject.csproj"); - InvokeDotnetTest($@"{projectPath} -nodereuse:false /p:PackageVersion={IntegrationTestEnvironment.LatestLocallyBuiltNugetVersion}", environmentVariables: new Dictionary { ["MSBUILDENSURESTDOUTFORTASKPROCESSES"] = "1" }); + InvokeDotnetTest($@"{projectPath} -nodereuse:false /p:PackageVersion={IntegrationTestEnvironment.LatestLocallyBuiltNugetVersion}", environmentVariables: new Dictionary { ["MSBUILDENSURESTDOUTFORTASKPROCESSES"] = "1" }, workingDirectory: Path.GetDirectoryName(projectPath)); // Check that we see the summary that is printed from the console logger, meaning the new output is disabled. StdOutputContains("Failed! - Failed: 1, Passed: 1, Skipped: 1, Total: 3, Duration:"); diff --git a/src/vstest/test/Microsoft.TestPlatform.Acceptance.IntegrationTests/DotnetTestTests.cs b/src/vstest/test/Microsoft.TestPlatform.Acceptance.IntegrationTests/DotnetTestTests.cs index 0332671357d..86f0dd308cf 100644 --- a/src/vstest/test/Microsoft.TestPlatform.Acceptance.IntegrationTests/DotnetTestTests.cs +++ b/src/vstest/test/Microsoft.TestPlatform.Acceptance.IntegrationTests/DotnetTestTests.cs @@ -26,7 +26,7 @@ public void RunDotnetTestWithCsproj(RunnerInfo runnerInfo) SetTestEnvironment(_testEnvironment, runnerInfo); var projectPath = GetIsolatedTestAsset("SimpleTestProject.csproj"); - InvokeDotnetTest($@"{projectPath} -p:VSTestUseMSBuildOutput=false --logger:""Console;Verbosity=normal"" /p:PackageVersion={IntegrationTestEnvironment.LatestLocallyBuiltNugetVersion}"); + InvokeDotnetTest($@"{projectPath} -p:VSTestUseMSBuildOutput=false --logger:""Console;Verbosity=normal"" /p:PackageVersion={IntegrationTestEnvironment.LatestLocallyBuiltNugetVersion}", workingDirectory: Path.GetDirectoryName(projectPath)); // ensure our dev version is used StdOutputContains(GetFinalVersion(IntegrationTestEnvironment.LatestLocallyBuiltNugetVersion)); @@ -43,7 +43,7 @@ public void RunDotnetTestWithDll(RunnerInfo runnerInfo) SetTestEnvironment(_testEnvironment, runnerInfo); var assemblyPath = GetAssetFullPath("SimpleTestProject.dll"); - InvokeDotnetTest($@"{assemblyPath} --logger:""Console;Verbosity=normal"""); + InvokeDotnetTest($@"{assemblyPath} --logger:""Console;Verbosity=normal""", workingDirectory: Path.GetDirectoryName(assemblyPath)); // ensure our dev version is used StdOutputContains(GetFinalVersion(IntegrationTestEnvironment.LatestLocallyBuiltNugetVersion)); @@ -60,7 +60,7 @@ public void RunDotnetTestWithCsprojPassInlineSettings(RunnerInfo runnerInfo) SetTestEnvironment(_testEnvironment, runnerInfo); var projectPath = GetIsolatedTestAsset("ParametrizedTestProject.csproj"); - InvokeDotnetTest($@"{projectPath} --logger:""Console;Verbosity=normal"" -p:VSTestUseMSBuildOutput=false /p:PackageVersion={IntegrationTestEnvironment.LatestLocallyBuiltNugetVersion} -- TestRunParameters.Parameter(name =\""weburl\"", value=\""http://localhost//def\"")"); + InvokeDotnetTest($@"{projectPath} --logger:""Console;Verbosity=normal"" -p:VSTestUseMSBuildOutput=false /p:PackageVersion={IntegrationTestEnvironment.LatestLocallyBuiltNugetVersion} -- TestRunParameters.Parameter(name =\""weburl\"", value=\""http://localhost//def\"")", workingDirectory: Path.GetDirectoryName(projectPath)); ValidateSummaryStatus(1, 0, 0); ExitCodeEquals(0); @@ -75,7 +75,7 @@ public void RunDotnetTestWithDllPassInlineSettings(RunnerInfo runnerInfo) SetTestEnvironment(_testEnvironment, runnerInfo); var assemblyPath = GetAssetFullPath("ParametrizedTestProject.dll"); - InvokeDotnetTest($@"{assemblyPath} --logger:""Console;Verbosity=normal"" -- TestRunParameters.Parameter(name=\""weburl\"", value=\""http://localhost//def\"")"); + InvokeDotnetTest($@"{assemblyPath} --logger:""Console;Verbosity=normal"" -- TestRunParameters.Parameter(name=\""weburl\"", value=\""http://localhost//def\"")", workingDirectory: Path.GetDirectoryName(assemblyPath)); ValidateSummaryStatus(1, 0, 0); ExitCodeEquals(0); @@ -93,7 +93,7 @@ public void RunDotnetTestWithNativeDll(RunnerInfo runnerInfo) string assemblyRelativePath = @"microsoft.testplatform.testasset.nativecpp\2.0.0\contentFiles\any\any\x64\Microsoft.TestPlatform.TestAsset.NativeCPP.dll"; var assemblyAbsolutePath = Path.Combine(_testEnvironment.PackageDirectory, assemblyRelativePath); - InvokeDotnetTest($@"{assemblyAbsolutePath} --logger:""Console;Verbosity=normal"" --diag:c:\temp\logscpp\"); + InvokeDotnetTest($@"{assemblyAbsolutePath} --logger:""Console;Verbosity=normal"" --diag:c:\temp\logscpp\", workingDirectory: Path.GetDirectoryName(assemblyAbsolutePath)); ValidateSummaryStatus(1, 1, 0); ExitCodeEquals(1); @@ -108,7 +108,7 @@ public void RunDotnetTestAndSeeOutputFromConsoleWriteLine(RunnerInfo runnerInfo) SetTestEnvironment(_testEnvironment, runnerInfo); var assemblyPath = GetAssetFullPath("OutputtingTestProject.dll"); - InvokeDotnetTest($@"{assemblyPath} --logger:""Console;Verbosity=normal"" "); + InvokeDotnetTest($@"{assemblyPath} --logger:""Console;Verbosity=normal"" ", workingDirectory: Path.GetDirectoryName(assemblyPath)); StdOutputContains("MY OUTPUT FROM TEST"); diff --git a/src/vstest/test/Microsoft.TestPlatform.Acceptance.IntegrationTests/Microsoft.TestPlatform.Acceptance.IntegrationTests.csproj b/src/vstest/test/Microsoft.TestPlatform.Acceptance.IntegrationTests/Microsoft.TestPlatform.Acceptance.IntegrationTests.csproj index c13550e38a4..b675da74546 100644 --- a/src/vstest/test/Microsoft.TestPlatform.Acceptance.IntegrationTests/Microsoft.TestPlatform.Acceptance.IntegrationTests.csproj +++ b/src/vstest/test/Microsoft.TestPlatform.Acceptance.IntegrationTests/Microsoft.TestPlatform.Acceptance.IntegrationTests.csproj @@ -4,10 +4,11 @@ true true true + $(TestRunnerAdditionalArguments) --settings "$(MSBuildThisFileDirectory)\.runsettings" - Exe + Exe net9.0;net48 diff --git a/src/vstest/test/Microsoft.TestPlatform.Acceptance.IntegrationTests/Program.cs b/src/vstest/test/Microsoft.TestPlatform.Acceptance.IntegrationTests/Program.cs deleted file mode 100644 index 360f5003ae1..00000000000 --- a/src/vstest/test/Microsoft.TestPlatform.Acceptance.IntegrationTests/Program.cs +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -#pragma warning disable IDE1006 // Naming Styles -namespace testhost.UnitTests; -#pragma warning restore IDE1006 // Naming Styles - -public static class Program -{ - public static void Main() - { - } -} diff --git a/src/vstest/test/Microsoft.TestPlatform.Acceptance.IntegrationTests/RunsettingsTests.cs b/src/vstest/test/Microsoft.TestPlatform.Acceptance.IntegrationTests/RunsettingsTests.cs index 3546759ab5b..4eec7dc7d02 100644 --- a/src/vstest/test/Microsoft.TestPlatform.Acceptance.IntegrationTests/RunsettingsTests.cs +++ b/src/vstest/test/Microsoft.TestPlatform.Acceptance.IntegrationTests/RunsettingsTests.cs @@ -307,6 +307,7 @@ public void LegacySettingsWithPlatform(RunnerInfo runnerInfo) } [TestMethod] + [Ignore("Ignore until we have new host available with CUIT removed.")] [TestCategory("Windows-Review")] [NetFullTargetFrameworkDataSourceAttribute(inIsolation: true, useCoreRunner: false)] public void LegacySettingsWithScripts(RunnerInfo runnerInfo) @@ -353,6 +354,7 @@ public void LegacySettingsWithScripts(RunnerInfo runnerInfo) } [TestMethod] + [Ignore("Ignore until we have new host available with CUIT removed.")] [TestCategory("Windows-Review")] [NetFullTargetFrameworkDataSourceAttribute(inIsolation: true, useCoreRunner: false)] public void LegacySettingsWithDeploymentItem(RunnerInfo runnerInfo) @@ -390,6 +392,7 @@ public void LegacySettingsWithDeploymentItem(RunnerInfo runnerInfo) } [TestMethod] + [Ignore("Ignore until we have new host available with CUIT removed.")] [TestCategory("Windows")] [NetFullTargetFrameworkDataSourceAttribute(inIsolation: true, useCoreRunner: false)] public void LegacySettingsTestTimeout(RunnerInfo runnerInfo) @@ -417,6 +420,7 @@ public void LegacySettingsTestTimeout(RunnerInfo runnerInfo) } [TestMethod] + [Ignore("Ignore until we have new host available with CUIT removed.")] [TestCategory("Windows-Review")] [NetFullTargetFrameworkDataSourceAttribute(inIsolation: true, useCoreRunner: false)] public void LegacySettingsAssemblyResolution(RunnerInfo runnerInfo) @@ -507,7 +511,7 @@ public void RunSettingsAreLoadedFromProject(RunnerInfo runnerInfo) var projectName = "ProjectFileRunSettingsTestProject.csproj"; var projectPath = GetIsolatedTestAsset(projectName); - InvokeDotnetTest($@"{projectPath} /p:VSTestUseMSBuildOutput=false --logger:""Console;Verbosity=normal"" /p:PackageVersion={IntegrationTestEnvironment.LatestLocallyBuiltNugetVersion}"); + InvokeDotnetTest($@"{projectPath} /p:VSTestUseMSBuildOutput=false --logger:""Console;Verbosity=normal"" /p:PackageVersion={IntegrationTestEnvironment.LatestLocallyBuiltNugetVersion}", workingDirectory: Path.GetDirectoryName(projectPath)); ValidateSummaryStatus(0, 1, 0); // make sure that we can revert the project settings back by providing a config from command line @@ -515,7 +519,7 @@ public void RunSettingsAreLoadedFromProject(RunnerInfo runnerInfo) // are honored by dotnet test, instead of just using the default, which would produce the same // result var settingsPath = GetProjectAssetFullPath(projectName, "inconclusive.runsettings"); - InvokeDotnetTest($@"{projectPath} --settings {settingsPath} /p:VSTestUseMSBuildOutput=false --logger:""Console;Verbosity=normal"" /p:PackageVersion={IntegrationTestEnvironment.LatestLocallyBuiltNugetVersion}"); + InvokeDotnetTest($@"{projectPath} --settings {settingsPath} /p:VSTestUseMSBuildOutput=false --logger:""Console;Verbosity=normal"" /p:PackageVersion={IntegrationTestEnvironment.LatestLocallyBuiltNugetVersion}", workingDirectory: Path.GetDirectoryName(projectPath)); ValidateSummaryStatus(0, 0, 1); } diff --git a/src/vstest/test/Microsoft.TestPlatform.Acceptance.IntegrationTests/TestPlatformNugetPackageTests.cs b/src/vstest/test/Microsoft.TestPlatform.Acceptance.IntegrationTests/TestPlatformNugetPackageTests.cs index 5f55b852eb3..712e00b6e86 100644 --- a/src/vstest/test/Microsoft.TestPlatform.Acceptance.IntegrationTests/TestPlatformNugetPackageTests.cs +++ b/src/vstest/test/Microsoft.TestPlatform.Acceptance.IntegrationTests/TestPlatformNugetPackageTests.cs @@ -22,6 +22,7 @@ public static void ClassInit(TestContext _) [TestMethod] [TestCategory("Windows-Review")] + [Ignore("Code Coverage is using 17.x.x dependency, will be solved in other PR. https://github.com/microsoft/vstest/issues/15223")] [NetFullTargetFrameworkDataSourceAttribute(useCoreRunner: false)] [NetCoreTargetFrameworkDataSourceAttribute(useCoreRunner: false)] public void RunMultipleTestAssembliesWithCodeCoverage(RunnerInfo runnerInfo) diff --git a/src/vstest/test/Microsoft.TestPlatform.Acceptance.IntegrationTests/TranslationLayerTests/CustomTestHostTests.cs b/src/vstest/test/Microsoft.TestPlatform.Acceptance.IntegrationTests/TranslationLayerTests/CustomTestHostTests.cs index 9996f086e0f..cdff53add3f 100644 --- a/src/vstest/test/Microsoft.TestPlatform.Acceptance.IntegrationTests/TranslationLayerTests/CustomTestHostTests.cs +++ b/src/vstest/test/Microsoft.TestPlatform.Acceptance.IntegrationTests/TranslationLayerTests/CustomTestHostTests.cs @@ -1,9 +1,12 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. +using System; using System.Collections.Generic; using System.Diagnostics; +using System.IO; using System.Linq; +using System.Text; using System.Threading; using FluentAssertions; @@ -140,7 +143,8 @@ public void RunTestsWithCustomTestHostLauncherUsesLaunchWhenGivenAnOutdatedITest [TestMethod] [TestCategory("Windows-Review")] [TestCategory("Feature")] - [RunnerCompatibilityDataSource(AfterFeature = Features.MULTI_TFM)] + // "Just row" used here because mstest does not cooperate with older versions of vstest.console correctly, so we test with just the latest version available.. + [RunnerCompatibilityDataSource(AfterFeature = Features.MULTI_TFM, JustRow = 0)] public void RunAllTestsWithMixedTFMsWillProvideAdditionalInformationToTheDebugger(RunnerInfo runnerInfo) { // Arrange @@ -158,6 +162,27 @@ public void RunAllTestsWithMixedTFMsWillProvideAdditionalInformationToTheDebugge vstestConsoleWrapper.RunTestsWithCustomTestHost(new[] { netFrameworkDll, netDll }, runsettingsXml, runEventHandler, testHostLauncher); // Assert + if (runEventHandler.Errors.Any()) + { + var tempPath = TempDirectory.Path; + var files = System.IO.Directory.GetFiles(tempPath, "*.txt").ToList(); + if (files.Count == 0) + { + throw new InvalidOperationException($"No error files found in {tempPath}. {string.Join("\n", Directory.GetFiles(tempPath))}"); + } + + var allText = new StringBuilder(); + foreach (var file in files) + { +#pragma warning disable CA1305 // Specify IFormatProvider + allText.AppendLine($"Error file: {file}"); + allText.AppendLine(File.ReadAllText(file)); + allText.AppendLine(); +#pragma warning restore CA1305 // Specify IFormatProvider + } + throw new InvalidOperationException($"Logs: {allText}"); + } + runEventHandler.Errors.Should().BeEmpty(); testHostLauncher.AttachDebuggerInfos.Should().HaveCount(2); var targetFrameworks = testHostLauncher.AttachDebuggerInfos.Select(i => i.TargetFramework).ToList(); diff --git a/src/vstest/test/Microsoft.TestPlatform.Acceptance.IntegrationTests/TranslationLayerTests/RunTestsWithDifferentConfigurationTests.cs b/src/vstest/test/Microsoft.TestPlatform.Acceptance.IntegrationTests/TranslationLayerTests/RunTestsWithDifferentConfigurationTests.cs index abf6f49b7b1..b7717d4fe50 100644 --- a/src/vstest/test/Microsoft.TestPlatform.Acceptance.IntegrationTests/TranslationLayerTests/RunTestsWithDifferentConfigurationTests.cs +++ b/src/vstest/test/Microsoft.TestPlatform.Acceptance.IntegrationTests/TranslationLayerTests/RunTestsWithDifferentConfigurationTests.cs @@ -102,7 +102,7 @@ public void RunTestsWithRunSettingsWithParallel(RunnerInfo runnerInfo) [TestMethod] [TestCategory("Windows-Review")] [NetFullTargetFrameworkDataSource()] - public void RunTestsWithTestSettings(RunnerInfo runnerInfo) + public void RunTestsWithTestSettingsInTpv2(RunnerInfo runnerInfo) { SetTestEnvironment(_testEnvironment, runnerInfo); ExecuteNotSupportedRunnerFrameworkTests(runnerInfo.RunnerFramework, NetFramework, Message); @@ -130,6 +130,72 @@ public void RunTestsWithTestSettings(RunnerInfo runnerInfo) Assert.AreEqual(1, _runEventHandler.TestResults.Count(t => t.Outcome == TestOutcome.Skipped)); } + [TestMethod] + [TestCategory("Windows-Review")] + [NetFullTargetFrameworkDataSource()] + public void RunTestsWithTestSettingsInTpv0(RunnerInfo runnerInfo) + { + SetTestEnvironment(_testEnvironment, runnerInfo); + ExecuteNotSupportedRunnerFrameworkTests(runnerInfo.RunnerFramework, NetFramework, Message); + Setup(); + + var testSettingsXml = """ + + + This is a default test run configuration for a local test run. + + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + + + + """; + + var testsettingsFile = Path.Combine(TempDirectory.Path, "tempsettings.testsettings"); + + File.WriteAllText(testsettingsFile, testSettingsXml, Encoding.UTF8); + + var source = GetAssetFullPath("MstestV1UnitTestProject.dll"); + + InvokeVsTestForExecution(source, null, runnerInfo.TargetFramework, runSettings: testsettingsFile, null); + + // Assert + // Ensure that we are actually running via TPv0 provider. + StringAssert.Contains(StdOutWithWhiteSpace, "The test execution was delegated to legacy TestPlatform runner"); + + ValidateSummaryStatus(2, 2, 1); + ExitCodeEquals(1); // failing tests + StdErrHasTestRunFailedMessageButNoOtherError(); + } + [TestMethod] [NetFullTargetFrameworkDataSource] [NetCoreTargetFrameworkDataSource] diff --git a/src/vstest/test/Microsoft.TestPlatform.AdapterUtilities.UnitTests/Microsoft.TestPlatform.AdapterUtilities.UnitTests.csproj b/src/vstest/test/Microsoft.TestPlatform.AdapterUtilities.UnitTests/Microsoft.TestPlatform.AdapterUtilities.UnitTests.csproj index 3a908e87bc5..6fc895e272d 100644 --- a/src/vstest/test/Microsoft.TestPlatform.AdapterUtilities.UnitTests/Microsoft.TestPlatform.AdapterUtilities.UnitTests.csproj +++ b/src/vstest/test/Microsoft.TestPlatform.AdapterUtilities.UnitTests/Microsoft.TestPlatform.AdapterUtilities.UnitTests.csproj @@ -6,7 +6,7 @@ net9.0;net48 - Exe + Exe Microsoft.TestPlatform.AdapterUtilities.UnitTests true $(NoWarn);RS1024 diff --git a/src/vstest/test/Microsoft.TestPlatform.AdapterUtilities.UnitTests/Program.cs b/src/vstest/test/Microsoft.TestPlatform.AdapterUtilities.UnitTests/Program.cs deleted file mode 100644 index 873e849545f..00000000000 --- a/src/vstest/test/Microsoft.TestPlatform.AdapterUtilities.UnitTests/Program.cs +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -namespace Microsoft.TestPlatform.AdapterUtilities.UnitTests; - -public static class Program -{ - public static void Main() - { - } -} diff --git a/src/vstest/test/Microsoft.TestPlatform.Build.UnitTests/Microsoft.TestPlatform.Build.UnitTests.csproj b/src/vstest/test/Microsoft.TestPlatform.Build.UnitTests/Microsoft.TestPlatform.Build.UnitTests.csproj index 93638126374..a1197a83088 100644 --- a/src/vstest/test/Microsoft.TestPlatform.Build.UnitTests/Microsoft.TestPlatform.Build.UnitTests.csproj +++ b/src/vstest/test/Microsoft.TestPlatform.Build.UnitTests/Microsoft.TestPlatform.Build.UnitTests.csproj @@ -7,7 +7,7 @@ net9.0;net48 - Exe + Exe Microsoft.TestPlatform.Build.UnitTests diff --git a/src/vstest/test/Microsoft.TestPlatform.Build.UnitTests/Program.cs b/src/vstest/test/Microsoft.TestPlatform.Build.UnitTests/Program.cs deleted file mode 100644 index ff1507b8ea2..00000000000 --- a/src/vstest/test/Microsoft.TestPlatform.Build.UnitTests/Program.cs +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -namespace Microsoft.TestPlatform.Build.UnitTests; - -public static class Program -{ - public static void Main() - { - } -} diff --git a/src/vstest/test/Microsoft.TestPlatform.Client.UnitTests/Microsoft.TestPlatform.Client.UnitTests.csproj b/src/vstest/test/Microsoft.TestPlatform.Client.UnitTests/Microsoft.TestPlatform.Client.UnitTests.csproj index 5839ea296be..890481f9771 100644 --- a/src/vstest/test/Microsoft.TestPlatform.Client.UnitTests/Microsoft.TestPlatform.Client.UnitTests.csproj +++ b/src/vstest/test/Microsoft.TestPlatform.Client.UnitTests/Microsoft.TestPlatform.Client.UnitTests.csproj @@ -7,7 +7,7 @@ net9.0;net48 - Exe + Exe Microsoft.TestPlatform.Client.UnitTests diff --git a/src/vstest/test/Microsoft.TestPlatform.Client.UnitTests/Program.cs b/src/vstest/test/Microsoft.TestPlatform.Client.UnitTests/Program.cs deleted file mode 100644 index 2f6d8d1a576..00000000000 --- a/src/vstest/test/Microsoft.TestPlatform.Client.UnitTests/Program.cs +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -namespace Microsoft.VisualStudio.TestPlatform.Client.UnitTests; - -public static class Program -{ - public static void Main() - { - } -} diff --git a/src/vstest/test/Microsoft.TestPlatform.Common.UnitTests/Microsoft.TestPlatform.Common.UnitTests.csproj b/src/vstest/test/Microsoft.TestPlatform.Common.UnitTests/Microsoft.TestPlatform.Common.UnitTests.csproj index 37e4ae7b0f1..85a71355922 100644 --- a/src/vstest/test/Microsoft.TestPlatform.Common.UnitTests/Microsoft.TestPlatform.Common.UnitTests.csproj +++ b/src/vstest/test/Microsoft.TestPlatform.Common.UnitTests/Microsoft.TestPlatform.Common.UnitTests.csproj @@ -7,7 +7,7 @@ net9.0;net48 - Exe + Exe Microsoft.TestPlatform.Common.UnitTests diff --git a/src/vstest/test/Microsoft.TestPlatform.Common.UnitTests/Program.cs b/src/vstest/test/Microsoft.TestPlatform.Common.UnitTests/Program.cs deleted file mode 100644 index a5c6522e979..00000000000 --- a/src/vstest/test/Microsoft.TestPlatform.Common.UnitTests/Program.cs +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -namespace Microsoft.VisualStudio.TestPlatform.Common.UnitTests; - -public static class Program -{ - public static void Main() - { - } -} diff --git a/src/vstest/test/Microsoft.TestPlatform.CommunicationUtilities.Platform.UnitTests/Microsoft.TestPlatform.CommunicationUtilities.Platform.UnitTests.csproj b/src/vstest/test/Microsoft.TestPlatform.CommunicationUtilities.Platform.UnitTests/Microsoft.TestPlatform.CommunicationUtilities.Platform.UnitTests.csproj index 0605d93fd51..2e7b9725573 100644 --- a/src/vstest/test/Microsoft.TestPlatform.CommunicationUtilities.Platform.UnitTests/Microsoft.TestPlatform.CommunicationUtilities.Platform.UnitTests.csproj +++ b/src/vstest/test/Microsoft.TestPlatform.CommunicationUtilities.Platform.UnitTests/Microsoft.TestPlatform.CommunicationUtilities.Platform.UnitTests.csproj @@ -7,7 +7,7 @@ net9.0;net48 - Exe + Exe Microsoft.TestPlatform.CommunicationUtilities.PlatformTests diff --git a/src/vstest/test/Microsoft.TestPlatform.CommunicationUtilities.Platform.UnitTests/Program.cs b/src/vstest/test/Microsoft.TestPlatform.CommunicationUtilities.Platform.UnitTests/Program.cs deleted file mode 100644 index b8f2141385d..00000000000 --- a/src/vstest/test/Microsoft.TestPlatform.CommunicationUtilities.Platform.UnitTests/Program.cs +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -namespace Microsoft.TestPlatform.CommunicationUtilities.PlatformTests; - -public static class Program -{ - public static void Main() - { - } -} diff --git a/src/vstest/test/Microsoft.TestPlatform.CommunicationUtilities.UnitTests/Microsoft.TestPlatform.CommunicationUtilities.UnitTests.csproj b/src/vstest/test/Microsoft.TestPlatform.CommunicationUtilities.UnitTests/Microsoft.TestPlatform.CommunicationUtilities.UnitTests.csproj index 99354bbad17..5d883492d23 100644 --- a/src/vstest/test/Microsoft.TestPlatform.CommunicationUtilities.UnitTests/Microsoft.TestPlatform.CommunicationUtilities.UnitTests.csproj +++ b/src/vstest/test/Microsoft.TestPlatform.CommunicationUtilities.UnitTests/Microsoft.TestPlatform.CommunicationUtilities.UnitTests.csproj @@ -7,7 +7,7 @@ net9.0;net48 - Exe + Exe Microsoft.TestPlatform.CommunicationUtilities.UnitTests diff --git a/src/vstest/test/Microsoft.TestPlatform.CommunicationUtilities.UnitTests/Program.cs b/src/vstest/test/Microsoft.TestPlatform.CommunicationUtilities.UnitTests/Program.cs deleted file mode 100644 index a4932304d9d..00000000000 --- a/src/vstest/test/Microsoft.TestPlatform.CommunicationUtilities.UnitTests/Program.cs +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -namespace Microsoft.TestPlatform.CommunicationUtilities.UnitTests; - -public static class Program -{ - public static void Main() - { - } -} diff --git a/src/vstest/test/Microsoft.TestPlatform.CoreUtilities.UnitTests/Helpers/DotnetHostHelperTest.cs b/src/vstest/test/Microsoft.TestPlatform.CoreUtilities.UnitTests/Helpers/DotnetHostHelperTest.cs index ea802a56daf..39ca505872b 100644 --- a/src/vstest/test/Microsoft.TestPlatform.CoreUtilities.UnitTests/Helpers/DotnetHostHelperTest.cs +++ b/src/vstest/test/Microsoft.TestPlatform.CoreUtilities.UnitTests/Helpers/DotnetHostHelperTest.cs @@ -298,6 +298,7 @@ public void GetDotnetPathByArchitecture_DefaultInstallation_Win( Assert.AreEqual(found ? dotnetMuxer : null, muxerPath); } +#pragma warning disable MSTEST0042 // duplicate data row - TODO: Look more into it [DataTestMethod] [DataRow(PlatformArchitecture.X64, PlatformArchitecture.X64, "/usr/local/share/dotnet", "", true, PlatformOperatingSystem.OSX)] [DataRow(PlatformArchitecture.X64, PlatformArchitecture.ARM64, "/usr/local/share/dotnet/x64", "", true, PlatformOperatingSystem.OSX)] @@ -316,6 +317,7 @@ public void GetDotnetPathByArchitecture_DefaultInstallation_Win( [DataRow(PlatformArchitecture.X64, PlatformArchitecture.ARM64, "/usr/share/dotnet/x64", "", false, PlatformOperatingSystem.Unix, DotnetMuxerResolutionStrategy.DefaultInstallationLocation)] [DataRow(PlatformArchitecture.ARM64, PlatformArchitecture.X64, "/usr/share/dotnet", "", false, PlatformOperatingSystem.Unix, DotnetMuxerResolutionStrategy.DefaultInstallationLocation)] [DataRow(PlatformArchitecture.X64, PlatformArchitecture.X64, "/usr/share/dotnet", "", false, PlatformOperatingSystem.Unix, DotnetMuxerResolutionStrategy.DefaultInstallationLocation)] +#pragma warning restore MSTEST0042 public void GetDotnetPathByArchitecture_DefaultInstallation_Unix( PlatformArchitecture targetArchitecture, PlatformArchitecture platformArchitecture, diff --git a/src/vstest/test/Microsoft.TestPlatform.CoreUtilities.UnitTests/Microsoft.TestPlatform.CoreUtilities.UnitTests.csproj b/src/vstest/test/Microsoft.TestPlatform.CoreUtilities.UnitTests/Microsoft.TestPlatform.CoreUtilities.UnitTests.csproj index 0999799a025..c0f492aed2b 100644 --- a/src/vstest/test/Microsoft.TestPlatform.CoreUtilities.UnitTests/Microsoft.TestPlatform.CoreUtilities.UnitTests.csproj +++ b/src/vstest/test/Microsoft.TestPlatform.CoreUtilities.UnitTests/Microsoft.TestPlatform.CoreUtilities.UnitTests.csproj @@ -7,7 +7,7 @@ net9.0;net48 - Exe + Exe Microsoft.TestPlatform.CoreUtilities.UnitTests diff --git a/src/vstest/test/Microsoft.TestPlatform.CoreUtilities.UnitTests/Program.cs b/src/vstest/test/Microsoft.TestPlatform.CoreUtilities.UnitTests/Program.cs deleted file mode 100644 index f027d8d6ce7..00000000000 --- a/src/vstest/test/Microsoft.TestPlatform.CoreUtilities.UnitTests/Program.cs +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -namespace TestPlatform.CoreUtilities.UnitTests; - -/// -/// Main entry point for the command line runner. -/// -public static class Program -{ - public static void Main() - { - } -} diff --git a/src/vstest/test/Microsoft.TestPlatform.CrossPlatEngine.UnitTests/Discovery/DiscovererEnumeratorTests.cs b/src/vstest/test/Microsoft.TestPlatform.CrossPlatEngine.UnitTests/Discovery/DiscovererEnumeratorTests.cs index 3215c024a30..802f7de7bda 100644 --- a/src/vstest/test/Microsoft.TestPlatform.CrossPlatEngine.UnitTests/Discovery/DiscovererEnumeratorTests.cs +++ b/src/vstest/test/Microsoft.TestPlatform.CrossPlatEngine.UnitTests/Discovery/DiscovererEnumeratorTests.cs @@ -758,6 +758,7 @@ public static void Reset() } [FileExtension(".dll")] + [FileExtension(".exe")] [DefaultExecutorUri("discoverer://manageddlldiscoverer")] [Category("managed")] private class ManagedDllTestDiscoverer : DllTestDiscoverer @@ -781,6 +782,7 @@ public static void Reset() } [FileExtension(".dll")] + [FileExtension(".exe")] [DefaultExecutorUri("discoverer://nativedlldiscoverer")] [Category("native")] private class NativeDllTestDiscoverer : DllTestDiscoverer @@ -833,7 +835,7 @@ private static bool ShouldTestDiscovered(IEnumerable sources) var shouldTestDiscovered = false; foreach (var source in sources) { - if (source.Equals("native.dll") || source.Equals("managed.dll") || source.EndsWith("CrossPlatEngine.UnitTests.dll")) + if (source.Equals("native.dll") || source.Equals("managed.dll") || source.EndsWith("CrossPlatEngine.UnitTests.dll") || source.EndsWith("CrossPlatEngine.UnitTests.exe")) { shouldTestDiscovered = true; break; diff --git a/src/vstest/test/Microsoft.TestPlatform.CrossPlatEngine.UnitTests/Execution/RunTestsWithSourcesTests.cs b/src/vstest/test/Microsoft.TestPlatform.CrossPlatEngine.UnitTests/Execution/RunTestsWithSourcesTests.cs index ba5b3dd7287..89a81acd471 100644 --- a/src/vstest/test/Microsoft.TestPlatform.CrossPlatEngine.UnitTests/Execution/RunTestsWithSourcesTests.cs +++ b/src/vstest/test/Microsoft.TestPlatform.CrossPlatEngine.UnitTests/Execution/RunTestsWithSourcesTests.cs @@ -382,6 +382,7 @@ public void CallInvokeExecutor(LazyExtension Microsoft.TestPlatform.CrossPlatEngine.UnitTests net9.0;net48 - Exe + Exe diff --git a/src/vstest/test/Microsoft.TestPlatform.CrossPlatEngine.UnitTests/Program.cs b/src/vstest/test/Microsoft.TestPlatform.CrossPlatEngine.UnitTests/Program.cs deleted file mode 100644 index 79c3743c992..00000000000 --- a/src/vstest/test/Microsoft.TestPlatform.CrossPlatEngine.UnitTests/Program.cs +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -namespace Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.UnitTests; - -public static class Program -{ - public static void Main() - { - } -} diff --git a/src/vstest/test/Microsoft.TestPlatform.Extensions.BlameDataCollector.UnitTests/Microsoft.TestPlatform.Extensions.BlameDataCollector.UnitTests.csproj b/src/vstest/test/Microsoft.TestPlatform.Extensions.BlameDataCollector.UnitTests/Microsoft.TestPlatform.Extensions.BlameDataCollector.UnitTests.csproj index 1fe46f071b4..81efd08aad3 100644 --- a/src/vstest/test/Microsoft.TestPlatform.Extensions.BlameDataCollector.UnitTests/Microsoft.TestPlatform.Extensions.BlameDataCollector.UnitTests.csproj +++ b/src/vstest/test/Microsoft.TestPlatform.Extensions.BlameDataCollector.UnitTests/Microsoft.TestPlatform.Extensions.BlameDataCollector.UnitTests.csproj @@ -20,7 +20,7 @@ net9.0;net48 - Exe + Exe Microsoft.TestPlatform.Extensions.BlameDataCollector.UnitTests diff --git a/src/vstest/test/Microsoft.TestPlatform.Extensions.BlameDataCollector.UnitTests/Program.cs b/src/vstest/test/Microsoft.TestPlatform.Extensions.BlameDataCollector.UnitTests/Program.cs deleted file mode 100644 index 6333b3f0bc2..00000000000 --- a/src/vstest/test/Microsoft.TestPlatform.Extensions.BlameDataCollector.UnitTests/Program.cs +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -namespace Microsoft.TestPlatform.Extensions.BlameDataCollector.UnitTests; - -public static class Program -{ - public static void Main() - { - } -} diff --git a/src/vstest/test/Microsoft.TestPlatform.Extensions.HtmlLogger.UnitTests/Microsoft.TestPlatform.Extensions.HtmlLogger.UnitTests.csproj b/src/vstest/test/Microsoft.TestPlatform.Extensions.HtmlLogger.UnitTests/Microsoft.TestPlatform.Extensions.HtmlLogger.UnitTests.csproj index de607265a61..7708ce4b170 100644 --- a/src/vstest/test/Microsoft.TestPlatform.Extensions.HtmlLogger.UnitTests/Microsoft.TestPlatform.Extensions.HtmlLogger.UnitTests.csproj +++ b/src/vstest/test/Microsoft.TestPlatform.Extensions.HtmlLogger.UnitTests/Microsoft.TestPlatform.Extensions.HtmlLogger.UnitTests.csproj @@ -7,7 +7,7 @@ net9.0;net48 - Exe + Exe diff --git a/src/vstest/test/Microsoft.TestPlatform.Extensions.HtmlLogger.UnitTests/Program.cs b/src/vstest/test/Microsoft.TestPlatform.Extensions.HtmlLogger.UnitTests/Program.cs deleted file mode 100644 index 0df49b12a6f..00000000000 --- a/src/vstest/test/Microsoft.TestPlatform.Extensions.HtmlLogger.UnitTests/Program.cs +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -namespace Microsoft.TestPlatform.Extensions.HtmlLogger.UnitTests; - -public static class Program -{ - public static void Main() - { - } -} diff --git a/src/vstest/test/Microsoft.TestPlatform.Extensions.TrxLogger.UnitTests/Microsoft.TestPlatform.Extensions.TrxLogger.UnitTests.csproj b/src/vstest/test/Microsoft.TestPlatform.Extensions.TrxLogger.UnitTests/Microsoft.TestPlatform.Extensions.TrxLogger.UnitTests.csproj index 469621d3599..3df4825d3ee 100644 --- a/src/vstest/test/Microsoft.TestPlatform.Extensions.TrxLogger.UnitTests/Microsoft.TestPlatform.Extensions.TrxLogger.UnitTests.csproj +++ b/src/vstest/test/Microsoft.TestPlatform.Extensions.TrxLogger.UnitTests/Microsoft.TestPlatform.Extensions.TrxLogger.UnitTests.csproj @@ -7,7 +7,7 @@ net9.0;net48 - Exe + Exe Microsoft.TestPlatform.Extensions.TrxLogger.UnitTests diff --git a/src/vstest/test/Microsoft.TestPlatform.Extensions.TrxLogger.UnitTests/Program.cs b/src/vstest/test/Microsoft.TestPlatform.Extensions.TrxLogger.UnitTests/Program.cs deleted file mode 100644 index f3ba5448d24..00000000000 --- a/src/vstest/test/Microsoft.TestPlatform.Extensions.TrxLogger.UnitTests/Program.cs +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -namespace Microsoft.TestPlatform.Extensions.TrxLogger.UnitTests; - -public static class Program -{ - public static void Main() - { - } -} diff --git a/src/vstest/test/Microsoft.TestPlatform.ObjectModel.UnitTests/Microsoft.TestPlatform.ObjectModel.UnitTests.csproj b/src/vstest/test/Microsoft.TestPlatform.ObjectModel.UnitTests/Microsoft.TestPlatform.ObjectModel.UnitTests.csproj index 2f8a9682787..744ca8bb296 100644 --- a/src/vstest/test/Microsoft.TestPlatform.ObjectModel.UnitTests/Microsoft.TestPlatform.ObjectModel.UnitTests.csproj +++ b/src/vstest/test/Microsoft.TestPlatform.ObjectModel.UnitTests/Microsoft.TestPlatform.ObjectModel.UnitTests.csproj @@ -7,7 +7,7 @@ net9.0;net48 - Exe + Exe Microsoft.TestPlatform.ObjectModel.UnitTests diff --git a/src/vstest/test/Microsoft.TestPlatform.ObjectModel.UnitTests/Program.cs b/src/vstest/test/Microsoft.TestPlatform.ObjectModel.UnitTests/Program.cs deleted file mode 100644 index 3911cf3a230..00000000000 --- a/src/vstest/test/Microsoft.TestPlatform.ObjectModel.UnitTests/Program.cs +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -namespace Microsoft.TestPlatform.ObjectModel.UnitTests; - -public static class Program -{ - public static void Main() - { - } -} diff --git a/src/vstest/test/Microsoft.TestPlatform.ObjectModel.UnitTests/RunSettings/RunConfigurationTests.cs b/src/vstest/test/Microsoft.TestPlatform.ObjectModel.UnitTests/RunSettings/RunConfigurationTests.cs index cc548cd386b..c88336c7373 100644 --- a/src/vstest/test/Microsoft.TestPlatform.ObjectModel.UnitTests/RunSettings/RunConfigurationTests.cs +++ b/src/vstest/test/Microsoft.TestPlatform.ObjectModel.UnitTests/RunSettings/RunConfigurationTests.cs @@ -119,23 +119,23 @@ public void SetTargetFrameworkVersionShouldSetTargetFramework() { var runConfiguration = new RunConfiguration(); runConfiguration.TargetFrameworkVersion = FrameworkVersion.Framework35; - Equals(Framework.FromString("Framework35")!.Name, runConfiguration.TargetFramework!.Name); + Assert.AreEqual(Framework.FromString("Framework35")!.Name, runConfiguration.TargetFramework!.Name); Assert.AreEqual(FrameworkVersion.Framework35, runConfiguration.TargetFrameworkVersion); runConfiguration.TargetFrameworkVersion = FrameworkVersion.Framework40; - Equals(Framework.FromString("Framework40")!.Name, runConfiguration.TargetFramework.Name); + Assert.AreEqual(Framework.FromString("Framework40")!.Name, runConfiguration.TargetFramework.Name); Assert.AreEqual(FrameworkVersion.Framework40, runConfiguration.TargetFrameworkVersion); runConfiguration.TargetFrameworkVersion = FrameworkVersion.Framework45; - Equals(Framework.FromString("Framework45")!.Name, runConfiguration.TargetFramework.Name); + Assert.AreEqual(Framework.FromString("Framework45")!.Name, runConfiguration.TargetFramework.Name); Assert.AreEqual(FrameworkVersion.Framework45, runConfiguration.TargetFrameworkVersion); runConfiguration.TargetFrameworkVersion = FrameworkVersion.FrameworkCore10; - Equals(Framework.FromString("FrameworkCore10")!.Name, runConfiguration.TargetFramework.Name); + Assert.AreEqual(Framework.FromString("FrameworkCore10")!.Name, runConfiguration.TargetFramework.Name); Assert.AreEqual(FrameworkVersion.FrameworkCore10, runConfiguration.TargetFrameworkVersion); runConfiguration.TargetFrameworkVersion = FrameworkVersion.FrameworkUap10; - Equals(Framework.FromString("FrameworkUap10")!.Name, runConfiguration.TargetFramework.Name); + Assert.AreEqual(Framework.FromString("FrameworkUap10")!.Name, runConfiguration.TargetFramework.Name); Assert.AreEqual(FrameworkVersion.FrameworkUap10, runConfiguration.TargetFrameworkVersion); } diff --git a/src/vstest/test/Microsoft.TestPlatform.TestHostProvider.UnitTests/Hosting/DotnetTestHostManagerTests.cs b/src/vstest/test/Microsoft.TestPlatform.TestHostProvider.UnitTests/Hosting/DotnetTestHostManagerTests.cs index 997d4741f09..2ee8d94b3a9 100644 --- a/src/vstest/test/Microsoft.TestPlatform.TestHostProvider.UnitTests/Hosting/DotnetTestHostManagerTests.cs +++ b/src/vstest/test/Microsoft.TestPlatform.TestHostProvider.UnitTests/Hosting/DotnetTestHostManagerTests.cs @@ -86,7 +86,6 @@ public DotnetTestHostManagerTests() _mockProcessHelper.Setup(ph => ph.GetCurrentProcessFileName()).Returns(DefaultDotnetPath); _mockProcessHelper.Setup(ph => ph.GetTestEngineDirectory()).Returns(DefaultDotnetPath); _mockProcessHelper.Setup(ph => ph.GetCurrentProcessArchitecture()).Returns(PlatformArchitecture.X64); - _mockEnvironmentVariable.Setup(ev => ev.GetEnvironmentVariable(It.IsAny())).Returns(Path.GetDirectoryName(DefaultDotnetPath)!); _mockFileHelper.Setup(ph => ph.Exists(_defaultTestHostPath)).Returns(true); _mockFileHelper.Setup(ph => ph.Exists(DefaultDotnetPath)).Returns(true); diff --git a/src/vstest/test/Microsoft.TestPlatform.TestHostProvider.UnitTests/Microsoft.TestPlatform.TestHostProvider.UnitTests.csproj b/src/vstest/test/Microsoft.TestPlatform.TestHostProvider.UnitTests/Microsoft.TestPlatform.TestHostProvider.UnitTests.csproj index 4768c56dcba..09db15d7e8e 100644 --- a/src/vstest/test/Microsoft.TestPlatform.TestHostProvider.UnitTests/Microsoft.TestPlatform.TestHostProvider.UnitTests.csproj +++ b/src/vstest/test/Microsoft.TestPlatform.TestHostProvider.UnitTests/Microsoft.TestPlatform.TestHostProvider.UnitTests.csproj @@ -8,7 +8,7 @@ Microsoft.TestPlatform.TestHostProvider.UnitTests net9.0;net48 - Exe + Exe diff --git a/src/vstest/test/Microsoft.TestPlatform.TestHostProvider.UnitTests/Program.cs b/src/vstest/test/Microsoft.TestPlatform.TestHostProvider.UnitTests/Program.cs deleted file mode 100644 index 79c3743c992..00000000000 --- a/src/vstest/test/Microsoft.TestPlatform.TestHostProvider.UnitTests/Program.cs +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -namespace Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.UnitTests; - -public static class Program -{ - public static void Main() - { - } -} diff --git a/src/vstest/test/Microsoft.TestPlatform.TestUtilities/IntegrationTestBase.cs b/src/vstest/test/Microsoft.TestPlatform.TestUtilities/IntegrationTestBase.cs index d1fe09ace23..2fab9fa01ce 100644 --- a/src/vstest/test/Microsoft.TestPlatform.TestUtilities/IntegrationTestBase.cs +++ b/src/vstest/test/Microsoft.TestPlatform.TestUtilities/IntegrationTestBase.cs @@ -46,7 +46,7 @@ public class IntegrationTestBase protected readonly IntegrationTestEnvironment _testEnvironment; private readonly string _msTestPre3_0AdapterRelativePath = @"mstest.testadapter\{0}\build\_common".Replace('\\', Path.DirectorySeparatorChar); - private readonly string _msTestAdapterRelativePath = @"mstest.testadapter\{0}\build\{1}".Replace('\\', Path.DirectorySeparatorChar); + private readonly string _msTestAdapterRelativePath = @"mstest.testadapter\{0}\buildTransitive\{1}".Replace('\\', Path.DirectorySeparatorChar); private readonly string _nUnitTestAdapterRelativePath = @"nunit3testadapter\{0}\build".Replace('\\', Path.DirectorySeparatorChar); private readonly string _xUnitTestAdapterRelativePath = @"xunit.runner.visualstudio\{0}\build\{1}".Replace('\\', Path.DirectorySeparatorChar); @@ -196,8 +196,17 @@ public void InvokeVsTest(string? arguments, Dictionary? environ ///
/// Arguments provided to vstest.console.exe /// Environment variables to set to the started process. - public void InvokeDotnetTest(string arguments, Dictionary? environmentVariables = null) + /// + public void InvokeDotnetTest(string arguments, Dictionary? environmentVariables = null, string? workingDirectory = null) { + if (workingDirectory is not null && !File.Exists(Path.Combine(workingDirectory, "dotnet.config"))) + { + File.WriteAllText(Path.Combine(workingDirectory, "dotnet.config"), """ + [dotnet.test.runner] + name = "VSTest" + """); + } + var debugEnvironmentVariables = AddDebugEnvironmentVariables(environmentVariables); var vstestConsolePath = GetDotnetRunnerPath(); @@ -222,7 +231,7 @@ public void InvokeDotnetTest(string arguments, Dictionary? envi // https://github.com/dotnet/sdk/blob/main/src/Cli/dotnet/commands/dotnet-test/VSTestForwardingApp.cs#L30-L39 debugEnvironmentVariables["VSTEST_CONSOLE_PATH"] = vstestConsolePath; - IntegrationTestBase.ExecutePatchedDotnet("test", arguments, out _standardTestOutput, out _standardTestError, out _runnerExitCode, debugEnvironmentVariables); + IntegrationTestBase.ExecutePatchedDotnet("test", arguments, out _standardTestOutput, out _standardTestError, out _runnerExitCode, debugEnvironmentVariables, workingDirectory); FormatStandardOutCome(); } @@ -790,8 +799,9 @@ protected void ExecuteVsTestConsole(string? args, out string stdOut, out string /// /// /// Environment variables to set to the started process. + /// private static void ExecutePatchedDotnet(string command, string args, out string stdOut, out string stdError, out int exitCode, - Dictionary? environmentVariables = null) + Dictionary? environmentVariables = null, string? workingDirectory = null) { environmentVariables ??= new(); @@ -799,7 +809,7 @@ private static void ExecutePatchedDotnet(string command, string args, out string var executablePath = OSUtils.IsWindows ? @"dotnet.exe" : @"dotnet"; var patchedDotnetPath = Path.GetFullPath(Path.Combine(IntegrationTestEnvironment.RepoRootDirectory, "artifacts", "tmp", ".dotnet", executablePath)); - ExecuteApplication(patchedDotnetPath, string.Join(" ", command, args), out stdOut, out stdError, out exitCode, environmentVariables); + ExecuteApplication(patchedDotnetPath, string.Join(" ", command, args), out stdOut, out stdError, out exitCode, environmentVariables, workingDirectory); } protected static void ExecuteApplication(string path, string? args, out string stdOut, out string stdError, out int exitCode, @@ -855,6 +865,7 @@ protected static void ExecuteApplication(string path, string? args, out string s Console.WriteLine("IntegrationTestBase.Execute: Path = {0}", process.StartInfo.FileName); Console.WriteLine("IntegrationTestBase.Execute: Arguments = {0}", process.StartInfo.Arguments); + Console.WriteLine("IntegrationTestBase.Execute: WorkingDirectory = {0}", StringUtils.IsNullOrWhiteSpace(process.StartInfo.WorkingDirectory) ? $"(Current Directory) {Directory.GetCurrentDirectory()}" : process.StartInfo.WorkingDirectory); var stopwatch = new Stopwatch(); stopwatch.Start(); diff --git a/src/vstest/test/Microsoft.TestPlatform.Utilities.UnitTests/Microsoft.TestPlatform.Utilities.UnitTests.csproj b/src/vstest/test/Microsoft.TestPlatform.Utilities.UnitTests/Microsoft.TestPlatform.Utilities.UnitTests.csproj index 2247db2ab0f..86bbf395d82 100644 --- a/src/vstest/test/Microsoft.TestPlatform.Utilities.UnitTests/Microsoft.TestPlatform.Utilities.UnitTests.csproj +++ b/src/vstest/test/Microsoft.TestPlatform.Utilities.UnitTests/Microsoft.TestPlatform.Utilities.UnitTests.csproj @@ -8,7 +8,7 @@ net9.0;net48 - Exe + Exe Microsoft.TestPlatform.Utilities.UnitTests diff --git a/src/vstest/test/Microsoft.TestPlatform.Utilities.UnitTests/Program.cs b/src/vstest/test/Microsoft.TestPlatform.Utilities.UnitTests/Program.cs deleted file mode 100644 index 20f06189b89..00000000000 --- a/src/vstest/test/Microsoft.TestPlatform.Utilities.UnitTests/Program.cs +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -namespace Microsoft.TestPlatform.Utilities.UnitTests; - -public static class Program -{ - public static void Main() - { - } -} diff --git a/src/vstest/test/SettingsMigrator.UnitTests/SettingsMigrator.UnitTests.csproj b/src/vstest/test/SettingsMigrator.UnitTests/SettingsMigrator.UnitTests.csproj index b2eb1760e9c..60915654882 100644 --- a/src/vstest/test/SettingsMigrator.UnitTests/SettingsMigrator.UnitTests.csproj +++ b/src/vstest/test/SettingsMigrator.UnitTests/SettingsMigrator.UnitTests.csproj @@ -4,6 +4,7 @@ true true false + Exe diff --git a/src/vstest/test/TestAssets/ArchitectureSwitch/global.json b/src/vstest/test/TestAssets/ArchitectureSwitch/global.json deleted file mode 100644 index c8c7401e654..00000000000 --- a/src/vstest/test/TestAssets/ArchitectureSwitch/global.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "sdk": { - "version": "6.0.200-preview" - } -} \ No newline at end of file diff --git a/src/vstest/test/TestAssets/CUITTestProject/CUITTestProject.csproj b/src/vstest/test/TestAssets/CUITTestProject/CUITTestProject.csproj deleted file mode 100644 index 44dffdbef08..00000000000 --- a/src/vstest/test/TestAssets/CUITTestProject/CUITTestProject.csproj +++ /dev/null @@ -1,47 +0,0 @@ - - - - - true - true - - - - CUITTestProject - $(NetFrameworkMinimum) - Exe - - - - - ..\..\..\.packages\microsoft.visualstudio.cuit\$(TestPlatformExternalsVersion)\tools\net451\Microsoft.VisualStudio.QualityTools.CodedUITestFramework.dll - - - ..\..\..\.packages\microsoft.visualstudio.qualitytools\$(TestPlatformExternalsVersion)\tools\net451\Microsoft.VisualStudio.QualityTools.UnitTestFramework.dll - - - ..\..\..\.packages\microsoft.visualstudio.cuit\$(TestPlatformExternalsVersion)\tools\net451\Microsoft.VisualStudio.TestTools.UITest.Common.dll - - - ..\..\..\.packages\microsoft.visualstudio.cuit\$(TestPlatformExternalsVersion)\tools\net451\Microsoft.VisualStudio.TestTools.UITest.Extension.dll - - - ..\..\..\.packages\microsoft.visualstudio.cuit\$(TestPlatformExternalsVersion)\tools\net451\Microsoft.VisualStudio.TestTools.UITesting.dll - - - - - - - - $(TestPlatformExternalsVersion) - - - $(TestPlatformExternalsVersion) - - - - - - - diff --git a/src/vstest/test/TestAssets/CUITTestProject/CodedUITest1.cs b/src/vstest/test/TestAssets/CUITTestProject/CodedUITest1.cs deleted file mode 100644 index 808ac345d04..00000000000 --- a/src/vstest/test/TestAssets/CUITTestProject/CodedUITest1.cs +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using Microsoft.VisualStudio.TestTools.UITesting; -using Microsoft.VisualStudio.TestTools.UnitTesting; - -namespace CodedUITestProject -{ - [CodedUITest] - public class CodedUITestProject - { - [TestMethod] - public void CodedUITestMethod1() - { - UITestControl.Desktop.DrawHighlight(); - } - } -} diff --git a/src/vstest/test/TestAssets/QualityToolsAssets/BingWebTest/BingWebTest.csproj b/src/vstest/test/TestAssets/QualityToolsAssets/BingWebTest/BingWebTest.csproj index e9c0056a3f4..248b264e3e2 100644 --- a/src/vstest/test/TestAssets/QualityToolsAssets/BingWebTest/BingWebTest.csproj +++ b/src/vstest/test/TestAssets/QualityToolsAssets/BingWebTest/BingWebTest.csproj @@ -17,7 +17,6 @@ 10.0 $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages - False true @@ -54,24 +53,6 @@ PreserveNewest - - - - - False - - - False - - - False - - - False - - - - 6.0.0 4.0.0-beta.25359.1 17.10.0-beta1.24272.1 - 3.1.21 + 3.1.23 6.0.0 6.0.4 6.0.0 diff --git a/src/diagnostics/src/Microsoft.Diagnostics.NETCore.Client/DiagnosticsClient/DiagnosticsClientExceptions.cs b/src/diagnostics/src/Microsoft.Diagnostics.NETCore.Client/DiagnosticsClient/DiagnosticsClientExceptions.cs index e9c2f15c426..c49984572e2 100644 --- a/src/diagnostics/src/Microsoft.Diagnostics.NETCore.Client/DiagnosticsClient/DiagnosticsClientExceptions.cs +++ b/src/diagnostics/src/Microsoft.Diagnostics.NETCore.Client/DiagnosticsClient/DiagnosticsClientExceptions.cs @@ -21,6 +21,7 @@ public UnsupportedProtocolException(string msg) : base(msg) { } public class ServerNotAvailableException : DiagnosticsClientException { public ServerNotAvailableException(string msg) : base(msg) { } + public ServerNotAvailableException(string msg, Exception exception) : base(msg, exception) { } } // When the runtime responded with an error diff --git a/src/diagnostics/src/Microsoft.Diagnostics.NETCore.Client/DiagnosticsIpc/IpcTransport.cs b/src/diagnostics/src/Microsoft.Diagnostics.NETCore.Client/DiagnosticsIpc/IpcTransport.cs index 7d4fb0a909a..de15869988a 100644 --- a/src/diagnostics/src/Microsoft.Diagnostics.NETCore.Client/DiagnosticsIpc/IpcTransport.cs +++ b/src/diagnostics/src/Microsoft.Diagnostics.NETCore.Client/DiagnosticsIpc/IpcTransport.cs @@ -6,6 +6,7 @@ using System.IO; using System.IO.Pipes; using System.Linq; +using System.Net.Sockets; using System.Runtime.InteropServices; using System.Security.Principal; using System.Threading; @@ -20,6 +21,7 @@ internal abstract class IpcEndpoint ///
/// The amount of time to block attempting to connect /// A stream used for writing and reading data to and from the target .NET process + /// ServerNotAvailableException public abstract Stream Connect(TimeSpan timeout); /// @@ -29,6 +31,7 @@ internal abstract class IpcEndpoint /// /// A task that completes with a stream used for writing and reading data to and from the target .NET process. /// + /// ServerNotAvailableException public abstract Task ConnectAsync(CancellationToken token); /// @@ -51,66 +54,81 @@ internal static class IpcEndpointHelper { public static Stream Connect(IpcEndpointConfig config, TimeSpan timeout) { - if (config.Transport == IpcEndpointConfig.TransportType.NamedPipe) - { - NamedPipeClientStream namedPipe = new( - ".", - config.Address, - PipeDirection.InOut, - PipeOptions.None, - TokenImpersonationLevel.Impersonation); - namedPipe.Connect((int)timeout.TotalMilliseconds); - return namedPipe; - } - else if (config.Transport == IpcEndpointConfig.TransportType.UnixDomainSocket) + try { - IpcUnixDomainSocket socket = new(); - socket.Connect(new IpcUnixDomainSocketEndPoint(config.Address), timeout); - return new ExposedSocketNetworkStream(socket, ownsSocket: true); - } + if (config.Transport == IpcEndpointConfig.TransportType.NamedPipe) + { + NamedPipeClientStream namedPipe = new( + ".", + config.Address, + PipeDirection.InOut, + PipeOptions.None, + TokenImpersonationLevel.Impersonation); + namedPipe.Connect((int)timeout.TotalMilliseconds); + return namedPipe; + } + else if (config.Transport == IpcEndpointConfig.TransportType.UnixDomainSocket) + { + IpcUnixDomainSocket socket = new(); + socket.Connect(new IpcUnixDomainSocketEndPoint(config.Address), timeout); + return new ExposedSocketNetworkStream(socket, ownsSocket: true); + } #if DIAGNOSTICS_RUNTIME - else if (config.Transport == IpcEndpointConfig.TransportType.TcpSocket) - { - var tcpClient = new TcpClient (); - var endPoint = new IpcTcpSocketEndPoint(config.Address); - tcpClient.Connect(endPoint.EndPoint); - return tcpClient.GetStream(); - } + else if (config.Transport == IpcEndpointConfig.TransportType.TcpSocket) + { + var tcpClient = new TcpClient (); + var endPoint = new IpcTcpSocketEndPoint(config.Address); + tcpClient.Connect(endPoint.EndPoint); + return tcpClient.GetStream(); + } #endif - else + else + { + throw new ArgumentException($"Unsupported IpcEndpointConfig transport type {config.Transport}"); + } + + } + catch (SocketException ex) { - throw new ArgumentException($"Unsupported IpcEndpointConfig transport type {config.Transport}"); + throw new ServerNotAvailableException($"Unable to connect to the server. {ex.Message}", ex); } } public static async Task ConnectAsync(IpcEndpointConfig config, CancellationToken token) { - if (config.Transport == IpcEndpointConfig.TransportType.NamedPipe) - { - NamedPipeClientStream namedPipe = new( - ".", - config.Address, - PipeDirection.InOut, - PipeOptions.Asynchronous, - TokenImpersonationLevel.Impersonation); - - // Pass non-infinite timeout in order to cause internal connection algorithm - // to check the CancellationToken periodically. Otherwise, if the named pipe - // is waited using WaitNamedPipe with an infinite timeout, then the - // CancellationToken cannot be observed. - await namedPipe.ConnectAsync(int.MaxValue, token).ConfigureAwait(false); - - return namedPipe; - } - else if (config.Transport == IpcEndpointConfig.TransportType.UnixDomainSocket) + try { - IpcUnixDomainSocket socket = new(); - await socket.ConnectAsync(new IpcUnixDomainSocketEndPoint(config.Address), token).ConfigureAwait(false); - return new ExposedSocketNetworkStream(socket, ownsSocket: true); + if (config.Transport == IpcEndpointConfig.TransportType.NamedPipe) + { + NamedPipeClientStream namedPipe = new( + ".", + config.Address, + PipeDirection.InOut, + PipeOptions.Asynchronous, + TokenImpersonationLevel.Impersonation); + + // Pass non-infinite timeout in order to cause internal connection algorithm + // to check the CancellationToken periodically. Otherwise, if the named pipe + // is waited using WaitNamedPipe with an infinite timeout, then the + // CancellationToken cannot be observed. + await namedPipe.ConnectAsync(int.MaxValue, token).ConfigureAwait(false); + + return namedPipe; + } + else if (config.Transport == IpcEndpointConfig.TransportType.UnixDomainSocket) + { + IpcUnixDomainSocket socket = new(); + await socket.ConnectAsync(new IpcUnixDomainSocketEndPoint(config.Address), token).ConfigureAwait(false); + return new ExposedSocketNetworkStream(socket, ownsSocket: true); + } + else + { + throw new ArgumentException($"Unsupported IpcEndpointConfig transport type {config.Transport}"); + } } - else + catch (SocketException ex) { - throw new ArgumentException($"Unsupported IpcEndpointConfig transport type {config.Transport}"); + throw new ServerNotAvailableException($"Unable to connect to the server. {ex.Message}", ex); } } } @@ -221,10 +239,13 @@ internal class PidIpcEndpoint : IpcEndpoint { public static string IpcRootPath { get; } = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? @"\\.\pipe\" : Path.GetTempPath(); public static string DiagnosticsPortPattern { get; } = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? @"^dotnet-diagnostic-(\d+)$" : @"^dotnet-diagnostic-(\d+)-(\d+)-socket$"; - + // Format strings as private const members + private const string _defaultAddressFormatWindows = "dotnet-diagnostic-{0}"; + private const string _dsrouterAddressFormatWindows = "dotnet-diagnostic-dsrouter-{0}"; + private const string _defaultAddressFormatNonWindows = "dotnet-diagnostic-{0}-{1}-socket"; + private const string _dsrouterAddressFormatNonWindows = "dotnet-diagnostic-dsrouter-{0}-{1}-socket"; private int _pid; private IpcEndpointConfig _config; - /// /// Creates a reference to a .NET process's IPC Transport /// using the default rules for a given pid @@ -271,11 +292,11 @@ private static bool TryGetDefaultAddress(int pid, out string defaultAddress) if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { - defaultAddress = $"dotnet-diagnostic-{pid}"; + defaultAddress = string.Format(_defaultAddressFormatWindows, pid); try { - string dsrouterAddress = Directory.GetFiles(IpcRootPath, $"dotnet-diagnostic-dsrouter-{pid}").FirstOrDefault(); + string dsrouterAddress = Directory.GetFiles(IpcRootPath, string.Format(_dsrouterAddressFormatWindows, pid)).FirstOrDefault(); if (!string.IsNullOrEmpty(dsrouterAddress)) { defaultAddress = dsrouterAddress; @@ -287,11 +308,11 @@ private static bool TryGetDefaultAddress(int pid, out string defaultAddress) { try { - defaultAddress = Directory.GetFiles(IpcRootPath, $"dotnet-diagnostic-{pid}-*-socket") // Try best match. + defaultAddress = Directory.GetFiles(IpcRootPath, string.Format(_defaultAddressFormatNonWindows, pid, "*")) // Try best match. .OrderByDescending(f => new FileInfo(f).LastWriteTime) .FirstOrDefault(); - string dsrouterAddress = Directory.GetFiles(IpcRootPath, $"dotnet-diagnostic-dsrouter-{pid}-*-socket") // Try best match. + string dsrouterAddress = Directory.GetFiles(IpcRootPath, string.Format(_dsrouterAddressFormatNonWindows, pid, "*")) // Try best match. .OrderByDescending(f => new FileInfo(f).LastWriteTime) .FirstOrDefault(); @@ -332,8 +353,15 @@ public static string GetDefaultAddress(int pid) string msg = $"Unable to connect to Process {pid}."; if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { + int total_length = IpcRootPath.Length + string.Format(_defaultAddressFormatNonWindows, pid, "##########").Length; + if (total_length > 108) // This isn't perfect as we don't know the disambiguation key length. However it should catch most cases. + { + msg += "The total length of the diagnostic socket path may exceed 108 characters. " + + "Try setting the TMPDIR environment variable to a shorter path"; + } msg += $" Please verify that {IpcRootPath} is writable by the current user. " + "If the target process has environment variable TMPDIR set, please set TMPDIR to the same directory. " + + "Please also ensure that the target process has {TMPDIR}/dotnet-diagnostic-{pid}-{disambiguation_key}-socket shorter than 108 characters. " + "Please see https://aka.ms/dotnet-diagnostics-port for more information"; } throw new ServerNotAvailableException(msg); @@ -349,7 +377,7 @@ public static bool IsDefaultAddressDSRouter(int pid, string address) address = address.Substring(IpcRootPath.Length); } - string dsrouterAddress = $"dotnet-diagnostic-dsrouter-{pid}"; + string dsrouterAddress = string.Format(_dsrouterAddressFormatWindows, pid); return address.StartsWith(dsrouterAddress, StringComparison.OrdinalIgnoreCase); } diff --git a/src/diagnostics/src/Microsoft.Diagnostics.TestHelpers/SdkPrebuiltDebuggeeCompiler.cs b/src/diagnostics/src/Microsoft.Diagnostics.TestHelpers/SdkPrebuiltDebuggeeCompiler.cs index d397dd809e4..ebc4105d435 100644 --- a/src/diagnostics/src/Microsoft.Diagnostics.TestHelpers/SdkPrebuiltDebuggeeCompiler.cs +++ b/src/diagnostics/src/Microsoft.Diagnostics.TestHelpers/SdkPrebuiltDebuggeeCompiler.cs @@ -15,6 +15,15 @@ public class SdkPrebuiltDebuggeeCompiler : IDebuggeeCompiler public SdkPrebuiltDebuggeeCompiler(TestConfiguration config, string debuggeeName) { + if (string.IsNullOrEmpty(config.TargetConfiguration)) + { + throw new System.ArgumentException("TargetConfiguration must be set in the TestConfiguration"); + } + if (string.IsNullOrEmpty(config.BuildProjectFramework)) + { + throw new System.ArgumentException("BuildProjectFramework must be set in the TestConfiguration"); + } + // The layout is how the current .NET Core SDK layouts the binaries out: // Source Path: //[] // Binary Path: /bin/// diff --git a/src/diagnostics/src/tests/CommonTestRunner/TestRunner.cs b/src/diagnostics/src/tests/CommonTestRunner/TestRunner.cs index 730dac25d1e..47497f6826d 100644 --- a/src/diagnostics/src/tests/CommonTestRunner/TestRunner.cs +++ b/src/diagnostics/src/tests/CommonTestRunner/TestRunner.cs @@ -49,6 +49,10 @@ public static async Task Create(TestConfiguration config, ITestOutpu // Get the full debuggee launch command line (includes the host if required) string exePath = debuggeeConfig.BinaryExePath; + if (!File.Exists(exePath)) + { + throw new FileNotFoundException($"Expected to find target executable at {exePath} but it didn't exist. Perhaps the path was improperly configured or a build/deployment error caused the file to be missing?"); + } string pipeName = null; StringBuilder arguments = new(); diff --git a/src/diagnostics/src/tests/Microsoft.Diagnostics.Monitoring.EventPipe/EventCounterPipelineUnitTests.cs b/src/diagnostics/src/tests/Microsoft.Diagnostics.Monitoring.EventPipe/EventCounterPipelineUnitTests.cs index 973e2d5a8cd..2fb091ea9bf 100644 --- a/src/diagnostics/src/tests/Microsoft.Diagnostics.Monitoring.EventPipe/EventCounterPipelineUnitTests.cs +++ b/src/diagnostics/src/tests/Microsoft.Diagnostics.Monitoring.EventPipe/EventCounterPipelineUnitTests.cs @@ -59,8 +59,9 @@ private sealed class TestMetricsLogger : ICountersLogger private readonly List _expectedCounters = new(); private Dictionary _metrics = new(); private readonly TaskCompletionSource _foundExpectedCountersSource; + private readonly ITestOutputHelper _output; - public TestMetricsLogger(IEnumerable expectedCounters, TaskCompletionSource foundExpectedCountersSource) + public TestMetricsLogger(IEnumerable expectedCounters, TaskCompletionSource foundExpectedCountersSource, ITestOutputHelper output) { _foundExpectedCountersSource = foundExpectedCountersSource; _expectedCounters = new(expectedCounters); @@ -68,6 +69,7 @@ public TestMetricsLogger(IEnumerable expectedCounters, TaskComp { foundExpectedCountersSource.SetResult(null); } + _output = output; } public IEnumerable Metrics => _metrics.Values; @@ -90,17 +92,29 @@ public void Log(ICounterPayload payload) ExpectedCounter expectedCounter = _expectedCounters.Find(c => c.MatchesCounterMetadata(payload.CounterMetadata)); if(expectedCounter != null) { + _expectedCounters.Remove(expectedCounter); _metrics.Add(expectedCounter, payload); + + _output.WriteLine($"Found expected counter: {expectedCounter.ProviderName}/{expectedCounter.CounterName}. Counters remaining={_expectedCounters.Count}"); // Complete the task source if the last expected key was removed. if (_expectedCounters.Count == 0) { + _output.WriteLine($"All expected counters have been received. Signaling pipeline can exit."); _foundExpectedCountersSource.TrySetResult(null); } } + else + { + _output.WriteLine($"Received additional counter event: {payload.CounterMetadata.ProviderName}/{payload.CounterMetadata.CounterName}"); + } } - public Task PipelineStarted(CancellationToken token) => Task.CompletedTask; + public Task PipelineStarted(CancellationToken token) + { + _output.WriteLine("Counters pipeline is running. Waiting to receive expected counters from tracee."); + return Task.CompletedTask; + } public Task PipelineStopped(CancellationToken token) => Task.CompletedTask; } @@ -113,7 +127,7 @@ public async Task TestCounterEventPipeline(TestConfiguration config) TaskCompletionSource foundExpectedCountersSource = new(TaskCreationOptions.RunContinuationsAsynchronously); - TestMetricsLogger logger = new(expectedCounters.Select(name => new ExpectedCounter(expectedProvider, name)), foundExpectedCountersSource); + TestMetricsLogger logger = new(expectedCounters.Select(name => new ExpectedCounter(expectedProvider, name)), foundExpectedCountersSource, _output); await using (TestRunner testRunner = await PipelineTestUtilities.StartProcess(config, "CounterRemoteTest", _output)) { @@ -169,7 +183,7 @@ public async Task TestDuplicateNameMetrics(TestConfiguration config) new ExpectedCounter(providerName, counterName, "MeterTag=two","InstrumentTag=B"), ]; TaskCompletionSource foundExpectedCountersSource = new(TaskCreationOptions.RunContinuationsAsynchronously); - TestMetricsLogger logger = new(expectedCounters, foundExpectedCountersSource); + TestMetricsLogger logger = new(expectedCounters, foundExpectedCountersSource, _output); await using (TestRunner testRunner = await PipelineTestUtilities.StartProcess(config, "DuplicateNameMetrics", _output, testProcessTimeout: 3_000)) { diff --git a/src/diagnostics/src/tests/Microsoft.Diagnostics.NETCore.Client/GetProcessInfoTests.cs b/src/diagnostics/src/tests/Microsoft.Diagnostics.NETCore.Client/GetProcessInfoTests.cs index 961ee8123e2..7f7181bc478 100644 --- a/src/diagnostics/src/tests/Microsoft.Diagnostics.NETCore.Client/GetProcessInfoTests.cs +++ b/src/diagnostics/src/tests/Microsoft.Diagnostics.NETCore.Client/GetProcessInfoTests.cs @@ -74,7 +74,22 @@ private async Task BasicProcessInfoTestCore(TestConfiguration config, bool useAs ProcessInfo processInfoBeforeResume = null; if (suspend) { - processInfoBeforeResume = await clientShim.GetProcessInfo(); + // when the process is just starting up, the IPC channel may not be ready yet. We need to be prepared for the connection attempt to fail. + // If 100 retries over 10 seconds fail then we'll go ahead and fail the test. + const int retryCount = 100; + for (int i = 0; i < retryCount; i++) + { + try + { + processInfoBeforeResume = await clientShim.GetProcessInfo(); + break; + } + catch (ServerNotAvailableException) when (i < retryCount-1) + { + _output.WriteLine($"Failed to connect to the IPC channel as the process is starting up. Attempt {i+1} of {retryCount}. Waiting 0.1 seconds, then retrying."); + await Task.Delay(100); + } + } ValidateProcessInfo(runner.Pid, processInfoBeforeResume); Assert.True((config.RuntimeFrameworkVersionMajor < 8) == string.IsNullOrEmpty(processInfoBeforeResume.ManagedEntrypointAssemblyName)); diff --git a/src/source-manifest.json b/src/source-manifest.json index 537842a0370..209c8a08dbb 100644 --- a/src/source-manifest.json +++ b/src/source-manifest.json @@ -31,10 +31,10 @@ "commitSha": "227da60247996ce95c272cdb5941163c669224e8" }, { - "barId": 275020, + "barId": 275333, "path": "diagnostics", "remoteUri": "https://github.com/dotnet/diagnostics", - "commitSha": "c3c57bbd7ce6950087b2e99be7a1a1170cf94923" + "commitSha": "15863918a40fc31d0498ca5f1b8a5f7f7ada113a" }, { "barId": 275325, From 7df312a4106f062f95684ec4a2c6c540be9ccdff Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Wed, 16 Jul 2025 13:32:04 +0000 Subject: [PATCH 14/18] [main] Source code updates from dotnet/winforms (#1505) [main] Source code updates from dotnet/winforms --- src/source-manifest.json | 4 +- src/winforms/eng/Version.Details.xml | 98 +++++++++---------- src/winforms/eng/Versions.props | 46 ++++----- src/winforms/global.json | 8 +- .../DataGridView/DataGridViewLinkCell.cs | 14 ++- .../Forms/Controls/Labels/LinkUtilities.cs | 12 +-- .../Windows/Forms/LinkUtilitiesTests.cs | 19 +--- 7 files changed, 93 insertions(+), 108 deletions(-) diff --git a/src/source-manifest.json b/src/source-manifest.json index 209c8a08dbb..9250a78b80f 100644 --- a/src/source-manifest.json +++ b/src/source-manifest.json @@ -139,10 +139,10 @@ "commitSha": "7890fbb7f086ae12b11ca85499b18f460c9090dd" }, { - "barId": 275147, + "barId": 275281, "path": "winforms", "remoteUri": "https://github.com/dotnet/winforms", - "commitSha": "17857aa725c3d0860f3aff0178d3b14817eb2266" + "commitSha": "6dd129e422c9b14dc835e669688247386bef2f95" }, { "barId": 274919, diff --git a/src/winforms/eng/Version.Details.xml b/src/winforms/eng/Version.Details.xml index d0791f836cd..b6532e2949e 100644 --- a/src/winforms/eng/Version.Details.xml +++ b/src/winforms/eng/Version.Details.xml @@ -6,106 +6,106 @@ Note: if the Uri is a new place, you will need to add a subscription from that p And you can check these with "darc get-dependencies target-repo "winforms" --> - + - + https://github.com/dotnet/dotnet - 0b032b9f942c1ae8de535a434c4f4a9206fd3339 + 3c34a3f0178f5a637d21c3f0ba5a4ee86ab8e976 - + https://github.com/dotnet/dotnet - 0b032b9f942c1ae8de535a434c4f4a9206fd3339 + 3c34a3f0178f5a637d21c3f0ba5a4ee86ab8e976 - + https://github.com/dotnet/dotnet - 0b032b9f942c1ae8de535a434c4f4a9206fd3339 + 3c34a3f0178f5a637d21c3f0ba5a4ee86ab8e976 - + https://github.com/dotnet/dotnet - 0b032b9f942c1ae8de535a434c4f4a9206fd3339 + 3c34a3f0178f5a637d21c3f0ba5a4ee86ab8e976 - + https://github.com/dotnet/dotnet - 0b032b9f942c1ae8de535a434c4f4a9206fd3339 + 3c34a3f0178f5a637d21c3f0ba5a4ee86ab8e976 - + https://github.com/dotnet/dotnet - 0b032b9f942c1ae8de535a434c4f4a9206fd3339 + 3c34a3f0178f5a637d21c3f0ba5a4ee86ab8e976 - + https://github.com/dotnet/dotnet - 0b032b9f942c1ae8de535a434c4f4a9206fd3339 + 3c34a3f0178f5a637d21c3f0ba5a4ee86ab8e976 - + https://github.com/dotnet/dotnet - 0b032b9f942c1ae8de535a434c4f4a9206fd3339 + 3c34a3f0178f5a637d21c3f0ba5a4ee86ab8e976 - + https://github.com/dotnet/dotnet - 0b032b9f942c1ae8de535a434c4f4a9206fd3339 + 3c34a3f0178f5a637d21c3f0ba5a4ee86ab8e976 - + https://github.com/dotnet/dotnet - 0b032b9f942c1ae8de535a434c4f4a9206fd3339 + 3c34a3f0178f5a637d21c3f0ba5a4ee86ab8e976 - + https://github.com/dotnet/dotnet - 0b032b9f942c1ae8de535a434c4f4a9206fd3339 + 3c34a3f0178f5a637d21c3f0ba5a4ee86ab8e976 - + https://github.com/dotnet/dotnet - 0b032b9f942c1ae8de535a434c4f4a9206fd3339 + 3c34a3f0178f5a637d21c3f0ba5a4ee86ab8e976 - + https://github.com/dotnet/dotnet - 0b032b9f942c1ae8de535a434c4f4a9206fd3339 + 3c34a3f0178f5a637d21c3f0ba5a4ee86ab8e976 - + https://github.com/dotnet/dotnet - 0b032b9f942c1ae8de535a434c4f4a9206fd3339 + 3c34a3f0178f5a637d21c3f0ba5a4ee86ab8e976 - + https://github.com/dotnet/dotnet - 0b032b9f942c1ae8de535a434c4f4a9206fd3339 + 3c34a3f0178f5a637d21c3f0ba5a4ee86ab8e976 - + https://github.com/dotnet/dotnet - 0b032b9f942c1ae8de535a434c4f4a9206fd3339 + 3c34a3f0178f5a637d21c3f0ba5a4ee86ab8e976 - + https://github.com/dotnet/dotnet - 0b032b9f942c1ae8de535a434c4f4a9206fd3339 + 3c34a3f0178f5a637d21c3f0ba5a4ee86ab8e976 - + https://github.com/dotnet/dotnet - 0b032b9f942c1ae8de535a434c4f4a9206fd3339 + 3c34a3f0178f5a637d21c3f0ba5a4ee86ab8e976 - + https://github.com/dotnet/dotnet - 0b032b9f942c1ae8de535a434c4f4a9206fd3339 + 3c34a3f0178f5a637d21c3f0ba5a4ee86ab8e976 - + https://github.com/dotnet/dotnet - 0b032b9f942c1ae8de535a434c4f4a9206fd3339 + 3c34a3f0178f5a637d21c3f0ba5a4ee86ab8e976 - + https://github.com/dotnet/dotnet - 0b032b9f942c1ae8de535a434c4f4a9206fd3339 + 3c34a3f0178f5a637d21c3f0ba5a4ee86ab8e976 - + https://github.com/dotnet/dotnet - 0b032b9f942c1ae8de535a434c4f4a9206fd3339 + 3c34a3f0178f5a637d21c3f0ba5a4ee86ab8e976 - + https://github.com/dotnet/dotnet - 0b032b9f942c1ae8de535a434c4f4a9206fd3339 + 3c34a3f0178f5a637d21c3f0ba5a4ee86ab8e976 - + https://github.com/dotnet/dotnet - 0b032b9f942c1ae8de535a434c4f4a9206fd3339 + 3c34a3f0178f5a637d21c3f0ba5a4ee86ab8e976 diff --git a/src/winforms/eng/Versions.props b/src/winforms/eng/Versions.props index bd85b1a716a..215d3204b77 100644 --- a/src/winforms/eng/Versions.props +++ b/src/winforms/eng/Versions.props @@ -10,30 +10,30 @@ $(MajorVersion).$(MinorVersion).$(PatchVersion) false release - 10.0.0-preview.7.25363.101 - 10.0.0-preview.7.25363.101 + 10.0.0-preview.7.25364.102 + 10.0.0-preview.7.25364.102 - 10.0.0-preview.7.25363.101 - 10.0.0-preview.7.25363.101 + 10.0.0-preview.7.25364.102 + 10.0.0-preview.7.25364.102 5.0.0-preview.7.20320.5 - 10.0.0-preview.7.25363.101 + 10.0.0-preview.7.25364.102 6.1.0-preview.1.24511.1 - 10.0.0-preview.7.25363.101 - 10.0.0-preview.7.25363.101 - 10.0.0-preview.7.25363.101 - 10.0.0-preview.7.25363.101 - 10.0.0-preview.7.25363.101 - 10.0.0-preview.7.25363.101 - 10.0.0-preview.7.25363.101 - 10.0.0-preview.7.25363.101 + 10.0.0-preview.7.25364.102 + 10.0.0-preview.7.25364.102 + 10.0.0-preview.7.25364.102 + 10.0.0-preview.7.25364.102 + 10.0.0-preview.7.25364.102 + 10.0.0-preview.7.25364.102 + 10.0.0-preview.7.25364.102 + 10.0.0-preview.7.25364.102 10.0.0-preview.5.25227.101 - 10.0.0-preview.7.25363.101 - 10.0.0-preview.7.25363.101 - 10.0.0-preview.7.25363.101 - 10.0.0-preview.7.25363.101 - 10.0.0-preview.7.25363.101 + 10.0.0-preview.7.25364.102 + 10.0.0-preview.7.25364.102 + 10.0.0-preview.7.25364.102 + 10.0.0-preview.7.25364.102 + 10.0.0-preview.7.25364.102 @@ -46,16 +46,16 @@ - 10.0.0-beta.25363.101 - 10.0.0-beta.25363.101 - 10.0.0-beta.25363.101 + 10.0.0-beta.25364.102 + 10.0.0-beta.25364.102 + 10.0.0-beta.25364.102 17.4.0-preview-20220707-01 - - 3.0.0-pre.25 + + 3.0.0 3.1.0 3.0.6-alpha diff --git a/src/winforms/global.json b/src/winforms/global.json index d9436cc48d5..a274e977be5 100644 --- a/src/winforms/global.json +++ b/src/winforms/global.json @@ -21,11 +21,11 @@ } }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "10.0.0-beta.25363.101", - "Microsoft.DotNet.CMake.Sdk": "10.0.0-beta.25363.101", - "Microsoft.DotNet.Helix.Sdk": "10.0.0-beta.25363.101", + "Microsoft.DotNet.Arcade.Sdk": "10.0.0-beta.25364.102", + "Microsoft.DotNet.CMake.Sdk": "10.0.0-beta.25364.102", + "Microsoft.DotNet.Helix.Sdk": "10.0.0-beta.25364.102", "FIX-85B6-MERGE-9C38-CONFLICT": "1.0.0", - "Microsoft.NET.Sdk.IL": "10.0.0-preview.7.25363.101" + "Microsoft.NET.Sdk.IL": "10.0.0-preview.7.25364.102" }, "native-tools": { "cmake": "latest" diff --git a/src/winforms/src/System.Windows.Forms/System/Windows/Forms/Controls/DataGridView/DataGridViewLinkCell.cs b/src/winforms/src/System.Windows.Forms/System/Windows/Forms/Controls/DataGridView/DataGridViewLinkCell.cs index a964cedc7ab..89195caa137 100644 --- a/src/winforms/src/System.Windows.Forms/System/Windows/Forms/Controls/DataGridView/DataGridViewLinkCell.cs +++ b/src/winforms/src/System.Windows.Forms/System/Windows/Forms/Controls/DataGridView/DataGridViewLinkCell.cs @@ -949,7 +949,7 @@ private Rectangle PaintPrivate( Font? getHoverFont = null; bool isActive = (LinkState & LinkState.Active) == LinkState.Active; - LinkUtilities.EnsureLinkFonts(cellStyle.Font!, LinkBehavior, ref getLinkFont, ref getHoverFont, isActive); + LinkUtilities.EnsureLinkFonts(cellStyle.Font!, LinkBehavior, ref getLinkFont, ref getHoverFont); using Font linkFont = getLinkFont; using Font hoverFont = getHoverFont; @@ -1028,6 +1028,18 @@ private Rectangle PaintPrivate( valBounds, linkColor, flags); + + // add a visiting effect. + if (isActive) + { + TextRenderer.DrawText( + g, + formattedValueStr, + LinkState == LinkState.Hover ? hoverFont : linkFont, + new Rectangle(valBounds.X + 1, valBounds.Y, valBounds.Width, valBounds.Height), + linkColor, + flags); + } } } else if (cellCurrent && diff --git a/src/winforms/src/System.Windows.Forms/System/Windows/Forms/Controls/Labels/LinkUtilities.cs b/src/winforms/src/System.Windows.Forms/System/Windows/Forms/Controls/Labels/LinkUtilities.cs index 6d1511a0e0c..259e485424b 100644 --- a/src/winforms/src/System.Windows.Forms/System/Windows/Forms/Controls/Labels/LinkUtilities.cs +++ b/src/winforms/src/System.Windows.Forms/System/Windows/Forms/Controls/Labels/LinkUtilities.cs @@ -163,8 +163,7 @@ public static void EnsureLinkFonts( Font baseFont, LinkBehavior link, [AllowNull] ref Font linkFont, - [AllowNull] ref Font hoverLinkFont, - bool isActive = false) + [AllowNull] ref Font hoverLinkFont) { if (linkFont is not null && hoverLinkFont is not null) { @@ -210,15 +209,6 @@ public static void EnsureLinkFonts( style &= ~FontStyle.Underline; } - if (isActive) - { - style |= FontStyle.Bold; - } - else - { - style &= ~FontStyle.Bold; - } - hoverLinkFont = new Font(f, style); linkFont = hoverLinkFont; } diff --git a/src/winforms/src/test/unit/System.Windows.Forms/System/Windows/Forms/LinkUtilitiesTests.cs b/src/winforms/src/test/unit/System.Windows.Forms/System/Windows/Forms/LinkUtilitiesTests.cs index 2cdd2cc65b9..3b7d8d098b6 100644 --- a/src/winforms/src/test/unit/System.Windows.Forms/System/Windows/Forms/LinkUtilitiesTests.cs +++ b/src/winforms/src/test/unit/System.Windows.Forms/System/Windows/Forms/LinkUtilitiesTests.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Drawing; @@ -44,21 +44,4 @@ public void LinkUtilities_EnsureLinkFonts_CreatesExpectedFonts(LinkBehavior beha linkFont.Should().BeOfType(); hoverLinkFont.Should().BeOfType(); } - - [WinFormsTheory] - [InlineData(LinkBehavior.AlwaysUnderline)] - [InlineData(LinkBehavior.HoverUnderline)] - [InlineData(LinkBehavior.NeverUnderline)] - public void LinkUtilities_EnsureLinkFonts_CreatesExpectedFonts_WithActive(LinkBehavior behavior) - { - using Font baseFont = new("Arial", 12); - Font? linkFont = null; - Font? hoverLinkFont = null; - - Action act = () => LinkUtilities.EnsureLinkFonts(baseFont, behavior, ref linkFont, ref hoverLinkFont, isActive: true); - - act.Should().NotThrow(); - linkFont.Should().BeOfType(); - hoverLinkFont.Should().BeOfType(); - } } From 5510f92a6ec850bf5a08c0587af58075ec99c776 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Wed, 16 Jul 2025 13:32:06 +0000 Subject: [PATCH 15/18] [main] Source code updates from dotnet/wpf (#1508) [main] Source code updates from dotnet/wpf --- src/source-manifest.json | 4 +- src/wpf/eng/Version.Details.xml | 94 +++++++++---------- src/wpf/eng/Versions.props | 42 ++++----- src/wpf/global.json | 4 +- .../Resources/Theme/Dark.xaml | 1 + .../Resources/Theme/HC.xaml | 1 + .../Resources/Theme/Light.xaml | 1 + .../Styles/DataGrid.xaml | 1 + .../Styles/DatePicker.xaml | 19 ++-- .../Themes/Fluent.Dark.xaml | 11 ++- .../Themes/Fluent.HC.xaml | 11 ++- .../Themes/Fluent.Light.xaml | 11 ++- .../Themes/Fluent.xaml | 10 +- 13 files changed, 108 insertions(+), 102 deletions(-) diff --git a/src/source-manifest.json b/src/source-manifest.json index 9250a78b80f..3fefa47cea1 100644 --- a/src/source-manifest.json +++ b/src/source-manifest.json @@ -145,10 +145,10 @@ "commitSha": "6dd129e422c9b14dc835e669688247386bef2f95" }, { - "barId": 274919, + "barId": 275192, "path": "wpf", "remoteUri": "https://github.com/dotnet/wpf", - "commitSha": "46685670c98a9e003ca98df637f68092d3b2cb65" + "commitSha": "900946a8e06533fd7ea8909d91b0c879a7c1f9be" }, { "barId": 274010, diff --git a/src/wpf/eng/Version.Details.xml b/src/wpf/eng/Version.Details.xml index 8b10c203b59..f77ebd9f51c 100644 --- a/src/wpf/eng/Version.Details.xml +++ b/src/wpf/eng/Version.Details.xml @@ -1,104 +1,104 @@ - + - + https://github.com/dotnet/dotnet - 86117ef4343bab700dab871c416e55b22848cd52 + 0b032b9f942c1ae8de535a434c4f4a9206fd3339 - + https://github.com/dotnet/dotnet - 86117ef4343bab700dab871c416e55b22848cd52 + 0b032b9f942c1ae8de535a434c4f4a9206fd3339 - + https://github.com/dotnet/dotnet - 86117ef4343bab700dab871c416e55b22848cd52 + 0b032b9f942c1ae8de535a434c4f4a9206fd3339 - + https://github.com/dotnet/dotnet - 86117ef4343bab700dab871c416e55b22848cd52 + 0b032b9f942c1ae8de535a434c4f4a9206fd3339 - + https://github.com/dotnet/dotnet - 86117ef4343bab700dab871c416e55b22848cd52 + 0b032b9f942c1ae8de535a434c4f4a9206fd3339 https://dev.azure.com/dnceng/internal/_git/dotnet-wpf-int 8a6c1d81657ef04c040f598cafacf8f5a33abda2 - + https://github.com/dotnet/dotnet - 86117ef4343bab700dab871c416e55b22848cd52 + 0b032b9f942c1ae8de535a434c4f4a9206fd3339 - + https://github.com/dotnet/dotnet - 86117ef4343bab700dab871c416e55b22848cd52 + 0b032b9f942c1ae8de535a434c4f4a9206fd3339 - + https://github.com/dotnet/dotnet - 86117ef4343bab700dab871c416e55b22848cd52 + 0b032b9f942c1ae8de535a434c4f4a9206fd3339 - + https://github.com/dotnet/dotnet - 86117ef4343bab700dab871c416e55b22848cd52 + 0b032b9f942c1ae8de535a434c4f4a9206fd3339 - + https://github.com/dotnet/dotnet - 86117ef4343bab700dab871c416e55b22848cd52 + 0b032b9f942c1ae8de535a434c4f4a9206fd3339 - + https://github.com/dotnet/dotnet - 86117ef4343bab700dab871c416e55b22848cd52 + 0b032b9f942c1ae8de535a434c4f4a9206fd3339 - + https://github.com/dotnet/dotnet - 86117ef4343bab700dab871c416e55b22848cd52 + 0b032b9f942c1ae8de535a434c4f4a9206fd3339 - + https://github.com/dotnet/dotnet - 86117ef4343bab700dab871c416e55b22848cd52 + 0b032b9f942c1ae8de535a434c4f4a9206fd3339 - + https://github.com/dotnet/dotnet - 86117ef4343bab700dab871c416e55b22848cd52 + 0b032b9f942c1ae8de535a434c4f4a9206fd3339 - + https://github.com/dotnet/dotnet - 86117ef4343bab700dab871c416e55b22848cd52 + 0b032b9f942c1ae8de535a434c4f4a9206fd3339 - + https://github.com/dotnet/dotnet - 86117ef4343bab700dab871c416e55b22848cd52 + 0b032b9f942c1ae8de535a434c4f4a9206fd3339 - + https://github.com/dotnet/dotnet - 86117ef4343bab700dab871c416e55b22848cd52 + 0b032b9f942c1ae8de535a434c4f4a9206fd3339 - + https://github.com/dotnet/dotnet - 86117ef4343bab700dab871c416e55b22848cd52 + 0b032b9f942c1ae8de535a434c4f4a9206fd3339 - + https://github.com/dotnet/dotnet - 86117ef4343bab700dab871c416e55b22848cd52 + 0b032b9f942c1ae8de535a434c4f4a9206fd3339 - + https://github.com/dotnet/dotnet - 86117ef4343bab700dab871c416e55b22848cd52 + 0b032b9f942c1ae8de535a434c4f4a9206fd3339 - + https://github.com/dotnet/dotnet - 86117ef4343bab700dab871c416e55b22848cd52 + 0b032b9f942c1ae8de535a434c4f4a9206fd3339 - + https://github.com/dotnet/dotnet - 86117ef4343bab700dab871c416e55b22848cd52 + 0b032b9f942c1ae8de535a434c4f4a9206fd3339 - + https://github.com/dotnet/dotnet - 86117ef4343bab700dab871c416e55b22848cd52 + 0b032b9f942c1ae8de535a434c4f4a9206fd3339 diff --git a/src/wpf/eng/Versions.props b/src/wpf/eng/Versions.props index 4899b503af3..c9a4bc5c364 100644 --- a/src/wpf/eng/Versions.props +++ b/src/wpf/eng/Versions.props @@ -19,33 +19,33 @@ dotnet/winforms is handling versions for the analyzers. --> $(MajorVersion).$(MinorVersion).0.0 - 10.0.0-beta.25360.101 - 10.0.0-beta.25360.101 - 10.0.0-beta.25360.101 + 10.0.0-beta.25363.101 + 10.0.0-beta.25363.101 + 10.0.0-beta.25363.101 - 10.0.0-preview.7.25360.101 - 10.0.0-preview.7.25360.101 - 10.0.0-preview.7.25360.101 + 10.0.0-preview.7.25363.101 + 10.0.0-preview.7.25363.101 + 10.0.0-preview.7.25363.101 - 10.0.0-preview.7.25360.101 - 10.0.0-preview.7.25360.101 - 10.0.0-preview.7.25360.101 - 10.0.0-preview.7.25360.101 - 10.0.0-preview.7.25360.101 - 10.0.0-preview.7.25360.101 - 10.0.0-preview.7.25360.101 - 10.0.0-preview.7.25360.101 - 10.0.0-preview.7.25360.101 + 10.0.0-preview.7.25363.101 + 10.0.0-preview.7.25363.101 + 10.0.0-preview.7.25363.101 + 10.0.0-preview.7.25363.101 + 10.0.0-preview.7.25363.101 + 10.0.0-preview.7.25363.101 + 10.0.0-preview.7.25363.101 + 10.0.0-preview.7.25363.101 + 10.0.0-preview.7.25363.101 4.6.0-preview4.19176.11 - 10.0.0-preview.7.25360.101 - 10.0.0-preview.7.25360.101 - 10.0.0-preview.7.25360.101 - 10.0.0-preview.7.25360.101 - 10.0.0-preview.7.25360.101 + 10.0.0-preview.7.25363.101 + 10.0.0-preview.7.25363.101 + 10.0.0-preview.7.25363.101 + 10.0.0-preview.7.25363.101 + 10.0.0-preview.7.25363.101 @@ -59,7 +59,7 @@ 9.0.0-beta.24053.1 - 10.0.0-beta.25360.101 + 10.0.0-beta.25363.101 diff --git a/src/wpf/global.json b/src/wpf/global.json index 9f82df38341..b479d6ad314 100644 --- a/src/wpf/global.json +++ b/src/wpf/global.json @@ -24,8 +24,8 @@ } }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "10.0.0-beta.25360.101", - "Microsoft.DotNet.Helix.Sdk": "10.0.0-beta.25360.101", + "Microsoft.DotNet.Arcade.Sdk": "10.0.0-beta.25363.101", + "Microsoft.DotNet.Helix.Sdk": "10.0.0-beta.25363.101", "Microsoft.Build.NoTargets": "3.7.56" }, "native-tools": { diff --git a/src/wpf/src/Microsoft.DotNet.Wpf/src/Themes/PresentationFramework.Fluent/Resources/Theme/Dark.xaml b/src/wpf/src/Microsoft.DotNet.Wpf/src/Themes/PresentationFramework.Fluent/Resources/Theme/Dark.xaml index 9456e48eff1..b3e08b806ca 100644 --- a/src/wpf/src/Microsoft.DotNet.Wpf/src/Themes/PresentationFramework.Fluent/Resources/Theme/Dark.xaml +++ b/src/wpf/src/Microsoft.DotNet.Wpf/src/Themes/PresentationFramework.Fluent/Resources/Theme/Dark.xaml @@ -532,6 +532,7 @@ + diff --git a/src/wpf/src/Microsoft.DotNet.Wpf/src/Themes/PresentationFramework.Fluent/Resources/Theme/HC.xaml b/src/wpf/src/Microsoft.DotNet.Wpf/src/Themes/PresentationFramework.Fluent/Resources/Theme/HC.xaml index 316b43b5248..1bbc712e822 100644 --- a/src/wpf/src/Microsoft.DotNet.Wpf/src/Themes/PresentationFramework.Fluent/Resources/Theme/HC.xaml +++ b/src/wpf/src/Microsoft.DotNet.Wpf/src/Themes/PresentationFramework.Fluent/Resources/Theme/HC.xaml @@ -351,6 +351,7 @@ + diff --git a/src/wpf/src/Microsoft.DotNet.Wpf/src/Themes/PresentationFramework.Fluent/Resources/Theme/Light.xaml b/src/wpf/src/Microsoft.DotNet.Wpf/src/Themes/PresentationFramework.Fluent/Resources/Theme/Light.xaml index 5a8fe89c121..1952082bb4d 100644 --- a/src/wpf/src/Microsoft.DotNet.Wpf/src/Themes/PresentationFramework.Fluent/Resources/Theme/Light.xaml +++ b/src/wpf/src/Microsoft.DotNet.Wpf/src/Themes/PresentationFramework.Fluent/Resources/Theme/Light.xaml @@ -548,6 +548,7 @@ + diff --git a/src/wpf/src/Microsoft.DotNet.Wpf/src/Themes/PresentationFramework.Fluent/Styles/DataGrid.xaml b/src/wpf/src/Microsoft.DotNet.Wpf/src/Themes/PresentationFramework.Fluent/Styles/DataGrid.xaml index edcc31d29d3..22aec44127d 100644 --- a/src/wpf/src/Microsoft.DotNet.Wpf/src/Themes/PresentationFramework.Fluent/Styles/DataGrid.xaml +++ b/src/wpf/src/Microsoft.DotNet.Wpf/src/Themes/PresentationFramework.Fluent/Styles/DataGrid.xaml @@ -404,6 +404,7 @@